json_to_usv/
lib.rs

1pub mod app {
2    pub mod args;
3    pub mod clap;
4    pub mod log;
5}
6pub mod examples;
7pub mod leaf;
8pub mod nest;
9
10use crate::nest::Nest;
11use usv::style::Style;
12
13pub fn json_to_usv<
14    S: AsRef<str> + Sized,
15>(
16    json: S,
17    style: &Style,
18) -> Result<String, serde_json::Error> {
19    let mut s = String::new();
20    match serde_json::from_str::<Nest>(json.as_ref())? {
21        Nest::Leaf(x) => {
22            s += &format!("{}", x);
23            s += &style.unit_separator;
24        },
25        Nest::V1(units) => {
26            for unit in units {
27                s += &format!("{}", unit);
28                s += &style.unit_separator;
29            }
30        },
31        Nest::V2(records) => {
32            for record in records {
33                for unit in record {
34                    s += &format!("{}", unit);
35                    s += &style.unit_separator;
36                }
37                s += &style.record_separator;
38            }
39        },
40        Nest::V3(groups) => {
41            for group in groups {
42                for record in group {
43                    for unit in record {
44                        s += &format!("{}", unit);
45                        s += &style.unit_separator;
46                    }
47                    s += &style.record_separator;
48                }
49                s += &style.group_separator;
50            }
51        },
52        Nest::V4(files) => {
53            for file in files {
54                for group in file {
55                    for record in group {
56                        for unit in record {
57                            s += &format!("{}", unit);
58                            s += &style.unit_separator;
59                        }
60                        s += &style.record_separator;
61                    }
62                    s += &style.group_separator;
63                }
64                s += &style.file_separator;
65            }
66        },
67        _ => {}
68    }
69    Ok(s)
70}
71
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use usv::style::Style;
77
78    #[test]
79    fn json_boolean() {
80        let json = String::from(r#"true"#);
81        let usv = String::from("true␟");
82        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
83    }
84
85    #[test]
86    fn json_number() {
87        let json = String::from(r#"123"#);
88        let usv = String::from("123␟");
89        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
90    }
91
92    #[test]
93    fn json_string() {
94        let json = String::from(r#""a""#);
95        let usv = String::from("a␟");
96        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
97    }
98
99    #[test]
100    fn json_array_dimension_1() {
101        let json = String::from(r#"["a","b"]"#);
102        let usv = String::from("a␟b␟");
103        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
104    }
105
106    #[test]
107    fn json_array_dimension_2() {
108        let json = String::from(r#"[["a","b"],["c","d"]]"#);
109        let usv = String::from("a␟b␟␞c␟d␟␞");
110        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
111    }
112
113    #[test]
114    fn json_array_dimension_3() {
115        let json = String::from(r#"[[["a","b"],["c","d"]],[["e","f"],["g","h"]]]"#);
116        let usv = String::from("a␟b␟␞c␟d␟␞␝e␟f␟␞g␟h␟␞␝");
117        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
118    }
119
120    #[test]
121    fn json_array_dimension_4() {
122        let json = String::from(r#"[[[["a","b"],["c","d"]],[["e","f"],["g","h"]]],[[["i","j"],["k","l"]],[["m","n"],["o","p"]]]]"#);
123        let usv = String::from("a␟b␟␞c␟d␟␞␝e␟f␟␞g␟h␟␞␝␜i␟j␟␞k␟l␟␞␝m␟n␟␞o␟p␟␞␝␜");
124        assert_eq!(json_to_usv(&json, &Style::default()).unwrap(), usv);
125    }
126
127}