nanvm_lib/app/
mod.rs

1use io_trait::Io;
2use std::io::{self, Error};
3
4use crate::{
5    common::default::default,
6    mem::global::GLOBAL,
7    parser::{
8        parser::{parse, Context},
9        shared::DataType,
10    },
11    serializer::{to_djs::to_djs, to_json::to_json},
12};
13
14pub fn run(io: &impl Io) -> io::Result<()> {
15    let mut a = io.args();
16    a.next().unwrap();
17    let input = a.next().unwrap();
18    let output = a.next().unwrap();
19
20    let mc = &mut default();
21    let mut context = Context::new(GLOBAL, io, input, mc);
22    let output_data_type = file_to_data_type(&output);
23    match output_data_type {
24        Ok(data_type) => match parse(&mut context) {
25            Ok(parse_result) => match data_type {
26                DataType::Json => {
27                    let to_json_result = to_json(parse_result.any);
28                    match to_json_result {
29                        Ok(s) => io.write(&output, s.as_bytes()),
30                        Err(e) => Err(Error::other(e)),
31                    }
32                }
33                DataType::Cjs => {
34                    let to_json_result = to_djs(parse_result.any, true);
35                    match to_json_result {
36                        Ok(s) => io.write(&output, s.as_bytes()),
37                        Err(e) => Err(Error::other(e)),
38                    }
39                }
40                DataType::Mjs => {
41                    let to_json_result = to_djs(parse_result.any, false);
42                    match to_json_result {
43                        Ok(s) => io.write(&output, s.as_bytes()),
44                        Err(e) => Err(Error::other(e)),
45                    }
46                }
47                _ => unreachable!(),
48            },
49            Err(parse_error) => Err(Error::other(parse_error.to_string())),
50        },
51        Err(e) => Err(e),
52    }
53}
54
55fn file_to_data_type(s: &str) -> Result<DataType, Error> {
56    if s.ends_with(".json") {
57        return Ok(DataType::Json);
58    }
59    if s.ends_with(".d.cjs") {
60        return Ok(DataType::Cjs);
61    }
62    if s.ends_with(".d.mjs") {
63        return Ok(DataType::Mjs);
64    }
65    Err(Error::other("invalid output extension"))
66}
67
68#[cfg(test)]
69mod test {
70    use io_test::VirtualIo;
71    use io_trait::Io;
72    use wasm_bindgen_test::wasm_bindgen_test;
73
74    use super::run;
75
76    #[test]
77    #[wasm_bindgen_test]
78    fn test_json() {
79        let io: VirtualIo = VirtualIo::new(&["test_json.json", "output.json"]);
80
81        let main = include_str!("../../test/test-json.json");
82        let main_path = "test_json.json";
83        io.write(main_path, main.as_bytes()).unwrap();
84
85        let result = run(&io);
86        assert!(result.is_ok());
87        let ouput_vec = io.read("output.json").unwrap();
88        let vec = String::from_utf8(ouput_vec).unwrap();
89        assert_eq!(vec, r#"{"key":[true,false,null]}"#);
90    }
91
92    #[test]
93    #[wasm_bindgen_test]
94    fn test_output_data_type() {
95        let io: VirtualIo = VirtualIo::new(&["test_json.json", "output.d.cjs"]);
96
97        let main = include_str!("../../test/test-json.json");
98        let main_path = "test_json.json";
99        io.write(main_path, main.as_bytes()).unwrap();
100
101        let result = run(&io);
102        assert!(result.is_ok());
103        let ouput_vec = io.read("output.d.cjs").unwrap();
104        let vec = String::from_utf8(ouput_vec).unwrap();
105        assert_eq!(vec, r#"module.exports={"key":[true,false,null]}"#);
106
107        let io: VirtualIo = VirtualIo::new(&["test_json.json", "output.d.mjs"]);
108
109        let main = include_str!("../../test/test-json.json");
110        let main_path = "test_json.json";
111        io.write(main_path, main.as_bytes()).unwrap();
112
113        let result = run(&io);
114        assert!(result.is_ok());
115        let ouput_vec = io.read("output.d.mjs").unwrap();
116        let vec = String::from_utf8(ouput_vec).unwrap();
117        assert_eq!(vec, r#"export default {"key":[true,false,null]}"#);
118    }
119
120    #[test]
121    #[wasm_bindgen_test]
122    fn test_cjs() {
123        let io: VirtualIo = VirtualIo::new(&["test_djs.d.cjs", "output.d.cjs"]);
124
125        let main = include_str!("../../test/test-djs.d.cjs");
126        let main_path = "test_djs.d.cjs";
127        io.write(main_path, main.as_bytes()).unwrap();
128
129        let result = run(&io);
130        assert!(result.is_ok());
131        let ouput_vec = io.read("output.d.cjs").unwrap();
132        let vec = String::from_utf8(ouput_vec).unwrap();
133        assert_eq!(vec, r#"module.exports={"id":null}"#);
134    }
135
136    #[test]
137    #[wasm_bindgen_test]
138    fn test_mjs() {
139        let io: VirtualIo = VirtualIo::new(&["test_djs.d.mjs", "output.d.mjs"]);
140
141        let main = include_str!("../../test/test-djs.d.mjs");
142        let main_path = "test_djs.d.mjs";
143        io.write(main_path, main.as_bytes()).unwrap();
144
145        let result = run(&io);
146        assert!(result.is_ok());
147        let ouput_vec = io.read("output.d.mjs").unwrap();
148        let vec = String::from_utf8(ouput_vec).unwrap();
149        assert_eq!(vec, r#"export default {"id":null}"#);
150    }
151
152    #[test]
153    #[wasm_bindgen_test]
154    fn test_cjs_import() {
155        let io: VirtualIo = VirtualIo::new(&["test_import_main.d.cjs", "output.d.cjs"]);
156
157        let main = include_str!("../../test/test_import_main.d.cjs");
158        let main_path = "test_import_main.d.cjs";
159        io.write(main_path, main.as_bytes()).unwrap();
160
161        let module = include_str!("../../test/test_import_module.d.cjs");
162        let module_path = "test_import_main.d.cjs";
163        io.write(module_path, module.as_bytes()).unwrap();
164
165        let result = run(&io);
166        assert!(result.is_ok());
167        let ouput_vec = io.read("output.d.cjs").unwrap();
168        let vec = String::from_utf8(ouput_vec).unwrap();
169        assert_eq!(vec, r#"module.exports=3"#);
170    }
171
172    #[test]
173    #[wasm_bindgen_test]
174    fn test_mjs_import() {
175        let io: VirtualIo = VirtualIo::new(&["test_import_main.d.mjs", "output.d.mjs"]);
176
177        let main = include_str!("../../test/test_import_main.d.mjs");
178        let main_path = "test_import_main.d.mjs";
179        io.write(main_path, main.as_bytes()).unwrap();
180
181        let module = include_str!("../../test/test_import_module.d.mjs");
182        let module_path = "test_import_main.d.mjs";
183        io.write(module_path, module.as_bytes()).unwrap();
184
185        let result = run(&io);
186        assert!(result.is_ok());
187        let ouput_vec = io.read("output.d.mjs").unwrap();
188        let vec = String::from_utf8(ouput_vec).unwrap();
189        assert_eq!(vec, r#"export default 4"#);
190    }
191
192    #[test]
193    #[wasm_bindgen_test]
194    fn test_invalid_ouput_extension() {
195        let io: VirtualIo = VirtualIo::new(&["test_json.json", "outputd.cjs"]);
196
197        let main = include_str!("../../test/test-json.json");
198        let main_path = "test_json.json";
199        io.write(main_path, main.as_bytes()).unwrap();
200
201        let result = run(&io);
202        assert!(result.is_err());
203    }
204}