<commit_before>use std::str::{self, FromStr};
use std::num::ParseIntError;
use std::collections::HashMap;

use nom::{IResult, ErrorKind, hex_digit, oct_digit, digit, is_alphanumeric, alpha, line_ending,
          not_line_ending, multispace, space};

// Copied and modified from rust-lang/rust/src/libcore/num/mod.rs
trait FromStrRadix: PartialOrd + Copy {
    type Err;
    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err>;
}

macro_rules! doit {
    ($($t:ty)*) => ($(impl FromStrRadix for $t {
        type Err = ParseIntError;
        fn from_str_radix(s: &str, r: u32) -> Result<$t, Self::Err> { Self::from_str_radix(s, r) }
    })*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

trait Labeled {
    fn add_label(&mut self, label: &str);
}

#[derive(PartialEq, Debug)]
pub struct BootInfo {
    pub reserve_info: Vec<ReserveInfo>,
    pub boot_cpuid: u32,
    pub root: Node,
}

#[derive(PartialEq, Debug)]
pub struct ReserveInfo {
    address: u64,
    size: u64,
    labels: Vec<String>,
}

impl Labeled for ReserveInfo {
    fn add_label(&mut self, label: &str) {
        let label = label.to_string();
        if !self.labels.contains(&label) {
            self.labels.push(label);
        }
    }
}

#[derive(PartialEq, Eq, Hash, Debug)]
pub enum Element<'a> {
    Node(&'a Node),
    Prop(&'a Property),
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Node {
    Deleted(String),
    Existing {
        name: String,
        proplist: Vec<Property>,
        children: Vec<Node>,

        // fullpath: Option<PathBuf>,
        // length to the # part of node_name@#
        // basenamelen: usize,
        //
        // phandle: u32,
        // addr_cells: i32,
        // size_cells: i32,
        labels: Vec<String>,
    }
}

impl Labeled for Node {
    fn add_label(&mut self, label: &str) {
        match *self {
            Node::Deleted(_) => panic!("Why are you adding a label to a deleted node?!"),
            Node::Existing{ ref mut labels, .. } => {
                let label = label.to_string();
                if labels.contains(&label) {
                    labels.push(label);
                }
            }
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Property {
    Deleted(String),
    Existing {
        name: String,
        val: Option<Vec<Data>>,
        labels: Vec<String>,
    }
}

impl Labeled for Property {
    fn add_label(&mut self, label: &str) {
        match *self {
            Property::Deleted(_) => panic!("Why are you adding a label to a deleted property?!"),
            Property::Existing{ ref mut labels, .. } => {
                let label = label.to_string();
                if labels.contains(&label) {
                    labels.push(label);
                }
            }
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Data {
    Reference(String),
    String(String),
    Cells(usize, Vec<(u64, Option<String>)>),
    ByteArray(Vec<u8>),
}

fn from_str_hex<T: FromStrRadix>(s: &str) -> Result<T, T::Err> {
    T::from_str_radix(s, 16)
}

fn from_str_oct<T: FromStrRadix>(s: &str) -> Result<T, T::Err> {
    T::from_str_radix(s, 8)
}
fn from_str_dec<T: FromStr>(s: &str) -> Result<T, T::Err> {
    T::from_str(s)<commit_msg>impl Display for Element, Node, Property, and Data<commit_after>use std::str::{self, FromStr};
use std::num::ParseIntError;
use std::collections::HashMap;
use std::fmt;

use nom::{IResult, ErrorKind, hex_digit, oct_digit, digit, is_alphanumeric, alpha, line_ending,
          not_line_ending, multispace, space};

// Copied and modified from rust-lang/rust/src/libcore/num/mod.rs
trait FromStrRadix: PartialOrd + Copy {
    type Err;
    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::Err>;
}

macro_rules! doit {
    ($($t:ty)*) => ($(impl FromStrRadix for $t {
        type Err = ParseIntError;
        fn from_str_radix(s: &str, r: u32) -> Result<$t, Self::Err> { Self::from_str_radix(s, r) }
    })*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

trait Labeled {
    fn add_label(&mut self, label: &str);
}

#[derive(PartialEq, Debug)]
pub struct BootInfo {
    pub reserve_info: Vec<ReserveInfo>,
    pub boot_cpuid: u32,
    pub root: Node,
}

#[derive(PartialEq, Debug)]
pub struct ReserveInfo {
    address: u64,
    size: u64,
    labels: Vec<String>,
}

impl Labeled for ReserveInfo {
    fn add_label(&mut self, label: &str) {
        let label = label.to_string();
        if !self.labels.contains(&label) {
            self.labels.push(label);
        }
    }
}

#[derive(PartialEq, Eq, Hash, Debug)]
pub enum Element<'a> {
    Node(&'a Node),
    Prop(&'a Property),
}

impl<'a> fmt::Display for Element<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Element::Node(ref node) => write!(f, "{}", node),
            Element::Prop(ref prop) => write!(f, "{}", prop),
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Node {
    Deleted(String),
    Existing {
        name: String,
        proplist: Vec<Property>,
        children: Vec<Node>,

        // fullpath: Option<PathBuf>,
        // length to the # part of node_name@#
        // basenamelen: usize,
        //
        // phandle: u32,
        // addr_cells: i32,
        // size_cells: i32,
        labels: Vec<String>,
    }
}

impl Labeled for Node {
    fn add_label(&mut self, label: &str) {
        match *self {
            Node::Deleted(_) => panic!("Why are you adding a label to a deleted node?!"),
            Node::Existing{ ref mut labels, .. } => {
                let label = label.to_string();
                if labels.contains(&label) {
                    labels.push(label);
                }
            }
        }
    }
}

impl fmt::Display for Node {
    // TODO: labels
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Node::Deleted(ref name) => write!(f, "// Node {} deleted", name)?,
            Node::Existing { ref name, ref proplist, ref children, .. } => {
                writeln!(f, "{} {{", name)?;
                for prop in proplist {
                    writeln!(f, "    {}", prop)?;
                }
                for node in children {
                    match *node {
                        Node::Deleted(ref name) =>
                            writeln!(f, "    // Node {} deleted", name)?,
                        Node::Existing { ref name, .. } =>
                            writeln!(f, "    {} {{ ... }}", name)?
                    }
                }
                write!(f, "}}")?;
            }
        }

        Ok(())
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Property {
    Deleted(String),
    Existing {
        name: String,
        val: Option<Vec<Data>>,
        labels: Vec<String>,
    }
}

impl Labeled for Property {
    fn add_label(&mut self, label: &str) {
        match *self {
            Property::Deleted(_) => panic!("Why are you adding a label to a deleted property?!"),
            Property::Existing{ ref mut labels, .. } => {
                let label = label.to_string();
                if labels.contains(&label) {
                    labels.push(label);
                }
            }
        }
    }
}

impl fmt::Display for Property {
    // TODO: labels
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Property::Deleted(ref name) => write!(f, "// Property {} deleted", name)?,
            Property::Existing { ref name, ref val, .. } => {
                write!(f, "{}", name)?;
                if let Some(ref data) = *val {
                    if !data.is_empty() {
                        let mut iter = data.iter();
                        write!(f, " = {}", iter.next().unwrap())?;
                        for d in iter {
                            write!(f, ", {}", d)?;
                        }
                    }
                }
                write!(f, ";")?;
            }
        }

        Ok(())
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Data {
    Reference(String),
    String(String),
    Cells(usize, Vec<(u64, Option<String>)>),
    ByteArray(Vec<u8>),
}

impl fmt::Display for Data {
    // TODO: labels
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Data::Reference(ref r) => write!(f, "&{}", r)?,
            Data::String(ref s) => write!(f, "{}", s)?,
            Data::Cells(bits, ref cells) => {
                if bits != 32 {
                    write!(f, "/bits/ {}", bits)?;
                }
                write!(f, "<")?;
                if !cells.is_empty() {
                    let mut iter = cells.iter();
                    match *iter.next().unwrap() {
                        (_, Some(ref s)) => write!(f, "&{}", s)?,
                        (i, None) => write!(f, "{}", i)?,
                    }
                    for d in iter {
                        match *d {
                            (_, Some(ref s)) => write!(f, ", &{}", s)?,
                            (i, None) => write!(f, ", {}", i)?,
                        }
                    }
                }
                write!(f, ">")?;
            }
            Data::ByteArray(ref arr) => {
                write!(f, "[ ")?;
                if !arr.is_empty() {
                    let mut iter = arr.iter();
                    write!(f, "{:02X}", iter.next().unwrap())?;
                    for d in iter{
                        write!(f, " {:02X}", d)?;
                    }
                }
                write!(f, " ]")?;
            }
        }

        Ok(())
    }
}

fn from_str_hex<T: FromStrRadix>(s: &str) -> Result<T, T::Err> {
    T::from_str_radix(s, 16)
}

fn from_str_oct<T: FromStrRadix>(s: &str) -> Result<T, T::Err> {
    T::from_str_radix(s, 8)
}
fn from_str_dec<T: FromStr>(s: &str) -> Result<T, T::Err> {
    T::from_str(s)
{'fraction_non_alphanumeric': 0.15978348035284684, 'fraction_numerical': 0.007818765036086608, 'mean_word_length': 1.7267012845039629, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 88, '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': '3553455', 'n_tokens_mistral': 3256, 'n_tokens_neox': 3209, 'n_words': 766}