1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
mod json; mod json_properties; mod lisplike; use std::str::FromStr; use std::vec::Vec; #[derive(Debug, PartialEq)] pub struct Node { pub name: String, pub children: Vec<Node>, } impl Node { pub fn new(name: String) -> Node { Node { name, children: Vec::new(), } } } pub enum InputFormat { LispLike, Json, JsonProperties, } impl FromStr for InputFormat { type Err = &'static str; fn from_str(s: &str) -> Result<Self, Self::Err> { match s { "lisp" => Ok(InputFormat::LispLike), "json" => Ok(InputFormat::Json), "jsonprop" => Ok(InputFormat::JsonProperties), _ => Err("invalid format type"), } } } #[derive(Debug, PartialEq)] pub enum Error { EmptyInputError, MissingPropError, MultipleRootsError, FormatSpecificError(String), } impl From<json5::Error> for Error { fn from(serde_error: json5::Error) -> Error { Error::FormatSpecificError(format!("{}", serde_error)) } } pub fn prettify( serialized: String, format: InputFormat, template: String, children_key: String, default: Option<String>, ) -> Result<String, Error> { let root = match format { InputFormat::LispLike => lisplike::deserialize(serialized), InputFormat::Json => json::deserialize(serialized), InputFormat::JsonProperties => { json_properties::deserialize(serialized, template, children_key, default) } }?; Ok(node_to_lines(&root).join("\n")) } pub fn node_to_lines(node: &Node) -> Vec<String> { let mut lines = vec![node.name.clone()]; let children = &node.children[..]; if let Some((last_child, non_last_children)) = children.split_last() { let child_node_lines = non_last_children.iter().flat_map(|child| { node_to_lines(child) .iter() .enumerate() .map(|(idx, child_line)| { if idx == 0 { format!("├── {}", child_line) } else { format!("│ {}", child_line) } }) .collect::<Vec<String>>() }); let last_child_node_lines = node_to_lines(last_child); let formatted_last_child_node_lines_iter = last_child_node_lines .iter() .enumerate() .map(|(idx, child_line)| { if idx == 0 { format!("└── {}", child_line) } else { format!(" {}", child_line) } }); let children_lines = child_node_lines.chain(formatted_last_child_node_lines_iter); lines.extend(children_lines); } lines }