<commit_before>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node 
///
struct TreeNodeEncoder<'a> {
    root: &'a mut MutableTreeNode
}

impl<'a> TreeNodeEncoder<'a> {
    fn new(root: &'a mut MutableTreeNode) -> TreeNodeEncoder<'a> {
        TreeNodeEncoder { root: root }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl<'a> Encoder for TreeNodeEncoder<'a> {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Nothing);
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v));
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Bool(v));
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v));
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v as f64));
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(v.to_string()));
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(name.to_string()));

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        // Insert a new node into the tree
        let new_node = BasicTree::new(f_name, ());

        self.root.get_child_ref().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Encode the field into the new node (would be super-elegant if this works but Rust is all 'nooope, you need to write a 
        // billion more lines of code'). I know *why* but this is stupid, if the encoder function had a better lifetime specifier
        // it'd be unnecessary.
        // Rust thinks that f() needs stuff with a lifetime the same as this struct rather than stuff with a lifetime as long
        // as the function call (it's not obvious from a casual reading of the definition, rust likes to be inscrutable). 
        // This means we need to do dumb stuff to make it work.
        /*
        let node_encoder = TreeNodeEncoder::new(&mut new_node);
        f(&mut node_encoder);
        */

        // Save the node we just created and update the tree
        self.root.set_child_ref(Rc::new(new_node));

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)<commit_msg>Can fix the lifetime thing by not making a lifetime part of the type, which means we can't directly encode to a TreeNode but instead need to encode something that can be made into a treenode later on<commit_after>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node 
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<Rc<TreeNode>>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder { 
            tag:    "".to_string(), 
            value:  TreeValue::Nothing,
            child:  None }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        // Insert a new node into the tree
        let new_node = BasicTree::new(f_name, ());

        self.child.to_owned().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Encode the field into the new node (would be super-elegant if this works but Rust is all 'nooope, you need to write a 
        // billion more lines of code'). I know *why* but this is stupid, if the encoder function had a better lifetime specifier
        // it'd be unnecessary.
        // Rust thinks that f() needs stuff with a lifetime the same as this struct rather than stuff with a lifetime as long
        // as the function call (it's not obvious from a casual reading of the definition, rust likes to be inscrutable). 
        // This means we need to do dumb stuff to make it work.
        let mut node_encoder = TreeNodeEncoder::new();
        f(&mut node_encoder);

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
{'fraction_non_alphanumeric': 0.13873473917869034, 'fraction_numerical': 0.006905907016894809, 'mean_word_length': 2.617305976806423, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '621612', 'n_tokens_mistral': 2639, 'n_tokens_neox': 2562, 'n_words': 837}