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
mod json;
mod json_properties;
mod parens;

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(),
        }
    }
}

impl render_as_tree::Node for Node {
    type Iter<'a> = std::slice::Iter<'a, Self>;
    fn name(&self) -> &str {
        &self.name
    }
    fn children(&self) -> Self::Iter<'_> {
        self.children.iter()
    }
}

pub enum InputFormat {
    Parens,
    Json,
    JsonProperties,
}

impl FromStr for InputFormat {
    type Err = &'static str;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "parens" => Ok(InputFormat::Parens),
            "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::Parens => parens::deserialize(serialized),
        InputFormat::Json => json::deserialize(serialized),
        InputFormat::JsonProperties => {
            json_properties::deserialize(serialized, template, children_key, default)
        }
    }?;
    Ok(render_as_tree::render(&root).join("\n"))
}