<commit_before>use crate::decor::{Formatted, Repr};
use crate::document::Document;
use crate::table::{Item, Table};
use crate::value::{Array, DateTime, InlineTable, Value};
use std::cell::{Cell, RefCell};
use std::fmt::{Display, Formatter, Result};

impl Display for Repr {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(
            f,
            "{}{}{}",
            self.decor.prefix, self.raw_value, self.decor.suffix
        )
    }
}

impl<T> Display for Formatted<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.repr)
    }
}

impl Display for DateTime {
    fn fmt(&self, f: &mut Formatter) -> Result {
        match *self {
            DateTime::OffsetDateTime(d) => write!(f, "{}", d),
            DateTime::LocalDateTime(d) => write!(f, "{}", d),
            DateTime::LocalDate(d) => write!(f, "{}", d),
            DateTime::LocalTime(d) => write!(f, "{}", d),
        }
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut Formatter) -> Result {
        match *self {
            Value::Integer(ref repr) => write!(f, "{}", repr),
            Value::String(ref repr) => write!(f, "{}", repr),
            Value::Float(ref repr) => write!(f, "{}", repr),
            Value::Boolean(ref repr) => write!(f, "{}", repr),
            Value::DateTime(ref repr) => write!(f, "{}", repr),
            Value::Array(ref array) => write!(f, "{}", array),
            Value::InlineTable(ref table) => write!(f, "{}", table),
        }
    }
}

impl Display for Array {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}[", self.decor.prefix)?;
        join(f, self.iter(), ",")?;
        if self.trailing_comma {
            write!(f, ",")?;
        }
        write!(f, "{}", self.trailing)?;
        write!(f, "]{}", self.decor.suffix)
    }
}

impl Display for InlineTable {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}{{", self.decor.prefix)?;
        write!(f, "{}", self.preamble)?;
        for (i, (key, value)) in self
            .items
            .iter()
            .filter(|&(_, kv)| kv.value.is_value())
            .map(|(_, kv)| (&kv.key, kv.value.as_value().unwrap()))
            .enumerate()
        {
            if i > 0 {
                write!(f, ",")?;
            }
            write!(f, "{}={}", key, value)?;
        }
        write!(f, "}}{}", self.decor.suffix)
    }
}

struct TableFormatState<'t> {
    path: RefCell<Vec<&'t str>>,
    table: Cell<&'t Table>,
}

impl<'a> Display for TableFormatState<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let table = self.table.get();

        for kv in table.items.values() {
            if let Item::Value(ref value) = kv.value {
                writeln!(f, "{}={}", kv.key, value)?;
            }
        }

        for kv in table.items.values() {
            match kv.value {
                Item::Table(ref t) => {
                    self.path.borrow_mut().push(&kv.key.raw_value);
                    self.table.set(t);
                    if !(t.implicit && t.values_len() == 0) {
                        write!(f, "{}[", t.decor.prefix)?;
                        write!(f, "{}", self.path.borrow().join("."))?;
                        writeln!(f, "]{}", t.decor.suffix)?;
                    }
                    write!(f, "{}", self)?;
                    self.table.set(table);
                    self.path.borrow_mut().pop();
                }
                Item::ArrayOfTables(ref a) => {
                    self.path.borrow_mut().push(&kv.key.raw_value);
                    for t in a.iter() {
                        self.table.set(t);
                        write!(f, "{}[[", t.decor.prefix)?;
                        write!(f, "{}", self.path.borrow().join("."))?;
                        writeln!(f, "]]{}", t.decor.suffix)?;
                        write!(f, "{}", self)?;
                    }
                    self.table.set(table);
                    self.path.borrow_mut().pop();
                }
                _ => {}
            }
        }
        Ok(())
    }
}

impl Display for Table {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let state = TableFormatState {
            path: RefCell::new(Vec::new()),
            table: Cell::new(self),
        };
        write!(f, "{}", state)
    }
}

impl Display for Document {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.as_table())?;
        write!(f, "{}", self.trailing)
    }
}

fn join<D, I>(f: &mut Formatter, iter: I, sep: &str) -> Result
where
    D: Display,
    I: Iterator<Item = D>,
{
    for (i, v) in iter.enumerate() {
        if i > 0 {
            write!(f, "{}", sep)?;
        }
        write!(f, "{}", v)?;
    }
    Ok(())
}<commit_msg>refactor impl Display for Table<commit_after>use crate::decor::{Formatted, Repr};
use crate::document::Document;
use crate::table::{Item, Table};
use crate::value::{Array, DateTime, InlineTable, Value};
use std::cell::{Cell, RefCell};
use std::fmt::{Display, Formatter, Result};

impl Display for Repr {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(
            f,
            "{}{}{}",
            self.decor.prefix, self.raw_value, self.decor.suffix
        )
    }
}

impl<T> Display for Formatted<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.repr)
    }
}

impl Display for DateTime {
    fn fmt(&self, f: &mut Formatter) -> Result {
        match *self {
            DateTime::OffsetDateTime(d) => write!(f, "{}", d),
            DateTime::LocalDateTime(d) => write!(f, "{}", d),
            DateTime::LocalDate(d) => write!(f, "{}", d),
            DateTime::LocalTime(d) => write!(f, "{}", d),
        }
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut Formatter) -> Result {
        match *self {
            Value::Integer(ref repr) => write!(f, "{}", repr),
            Value::String(ref repr) => write!(f, "{}", repr),
            Value::Float(ref repr) => write!(f, "{}", repr),
            Value::Boolean(ref repr) => write!(f, "{}", repr),
            Value::DateTime(ref repr) => write!(f, "{}", repr),
            Value::Array(ref array) => write!(f, "{}", array),
            Value::InlineTable(ref table) => write!(f, "{}", table),
        }
    }
}

impl Display for Array {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}[", self.decor.prefix)?;
        join(f, self.iter(), ",")?;
        if self.trailing_comma {
            write!(f, ",")?;
        }
        write!(f, "{}", self.trailing)?;
        write!(f, "]{}", self.decor.suffix)
    }
}

impl Display for InlineTable {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}{{", self.decor.prefix)?;
        write!(f, "{}", self.preamble)?;
        for (i, (key, value)) in self
            .items
            .iter()
            .filter(|&(_, kv)| kv.value.is_value())
            .map(|(_, kv)| (&kv.key, kv.value.as_value().unwrap()))
            .enumerate()
        {
            if i > 0 {
                write!(f, ",")?;
            }
            write!(f, "{}={}", key, value)?;
        }
        write!(f, "}}{}", self.decor.suffix)
    }
}

fn visit_nested_tables<'t, F>(
    table: &'t Table,
    path: &mut Vec<&'t str>,
    is_array_of_tables: bool,
    callback: &mut F,
) -> Result
where
    F: FnMut(&Table, &Vec<&'t str>, bool) -> Result,
{
    callback(table, path, is_array_of_tables)?;

    for kv in table.items.values() {
        match kv.value {
            Item::Table(ref t) => {
                path.push(&kv.key.raw_value);
                visit_nested_tables(t, path, false, callback)?;
                path.pop();
            }
            Item::ArrayOfTables(ref a) => {
                for t in a.iter() {
                    path.push(&kv.key.raw_value);
                    visit_nested_tables(t, path, true, callback)?;
                    path.pop();
                }
            }
            _ => {}
        }
    }
    Ok(())
}

impl Display for Table {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let mut path = Vec::new();

        visit_nested_tables(
            self,
            &mut path,
            false,
            &mut |t: &Table, path, is_array_of_tables: bool| {
                if path.len() == 0 {
                    // don't print header for the root node
                } else if is_array_of_tables {
                    write!(f, "{}[[", t.decor.prefix)?;
                    write!(f, "{}", path.join("."))?;
                    writeln!(f, "]]{}", t.decor.suffix)?;
                } else if !(t.implicit && t.values_len() == 0) {
                    write!(f, "{}[", t.decor.prefix)?;
                    write!(f, "{}", path.join("."))?;
                    writeln!(f, "]{}", t.decor.suffix)?;
                }
                // print table body
                for kv in t.items.values() {
                    if let Item::Value(ref value) = kv.value {
                        writeln!(f, "{}={}", kv.key, value)?;
                    }
                }
                Ok(())
            },
        )?;
        Ok(())
    }
}

impl Display for Document {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.as_table())?;
        write!(f, "{}", self.trailing)
    }
}

fn join<D, I>(f: &mut Formatter, iter: I, sep: &str) -> Result
where
    D: Display,
    I: Iterator<Item = D>,
{
    for (i, v) in iter.enumerate() {
        if i > 0 {
            write!(f, "{}", sep)?;
        }
        write!(f, "{}", v)?;
    }
    Ok(())
}
{'fraction_non_alphanumeric': 0.19579910575023396, 'fraction_numerical': 0.0007278777165436207, 'mean_word_length': 1.626433642818132, 'pattern_counts': {'":': 0, '<': 20, '<?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': '567879', 'n_tokens_mistral': 3084, 'n_tokens_neox': 3045, 'n_words': 652}