pub fn parse<'a>(
on: &'a str,
cb: impl for<'b> FnMut(&'b [JSONKey<'a>], RootJSONValue<'a>),
) -> Result<usize, JSONParseError>
Expand description
If you want to return early (break on an exception in the callback) or
more configuration use parse_with_exit_signal
ยงErrors
Returns an error if it tries to parse invalid JSON input
Examples found in repository?
examples/comments.rs (lines 12-14)
3fn main() {
4 let content = r#"// Something
5 {
6 "a": 2,
7 // Another
8 "b": 5,
9 # another comment
10 }"#;
11
12 let result = parse(content, |keys, value| {
13 eprintln!("{keys:?} -> {value:?}");
14 });
15
16 assert!(result.is_ok());
17}
More examples
examples/top_level.rs (lines 15-17)
3fn main() {
4 let to_parse = &[
5 "199",
6 "\"Hiya\"",
7 "[1, 2, \"something\"]",
8 "true",
9 "false",
10 "null",
11 ];
12
13 for item in to_parse {
14 eprintln!("parsing {item} as JSON");
15 let result = parse(item, |keys, value| {
16 eprintln!("{keys:?} -> {value:?}");
17 });
18
19 assert!(result.is_ok());
20 }
21}
examples/to_object_unsafe.rs (lines 31-72)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 let path = std::env::args().nth(1).ok_or("Expected first argument")?;
9 let content = std::fs::read_to_string(path)?;
10
11 pub type Object = HashMap<String, Value>;
12
13 #[derive(Debug)]
14 #[allow(dead_code)]
15 pub enum Value {
16 Object(Object),
17 String(String),
18 Number(String),
19 Boolean(bool),
20 Null,
21 }
22
23 impl Value {
24 pub fn new_empty_object() -> Self {
25 Self::Object(HashMap::new())
26 }
27 }
28
29 let mut root = Object::new();
30
31 let _res = parse(&content, |keys, value| {
32 let [path @ .., end] = keys else {
33 unreachable!("empty key change")
34 };
35 let pointer = &mut root;
36
37 let mut to_add_to: *mut Object = pointer;
38
39 for key in path {
40 let name = match key {
41 JSONKey::Slice(s) => (*s).to_string(),
42 JSONKey::Index(i) => i.to_string(),
43 };
44 if let Some(Value::Object(ref mut obj)) =
45 unsafe { (to_add_to.as_mut().unwrap()).get_mut(&name) }
46 {
47 to_add_to = obj;
48 } else {
49 let value = unsafe {
50 (to_add_to.as_mut().unwrap())
51 .entry(name)
52 .or_insert_with(Value::new_empty_object)
53 };
54 if let Value::Object(ref mut obj) = value {
55 to_add_to = obj;
56 }
57 }
58 }
59 let name = match end {
60 JSONKey::Slice(s) => (*s).to_string(),
61 JSONKey::Index(i) => i.to_string(),
62 };
63 let value = match value {
64 RootJSONValue::String(s) => Value::String(s.to_string()),
65 RootJSONValue::Number(n) => Value::Number(n.to_string()),
66 RootJSONValue::Boolean(v) => Value::Boolean(v),
67 RootJSONValue::Null => Value::Null,
68 };
69 unsafe {
70 (to_add_to.as_mut().unwrap()).insert(name, value);
71 }
72 });
73
74 eprintln!("Parsed: {root:#?}");
75 Ok(())
76}
examples/to_object.rs (line 60)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let path = std::env::args().nth(1).ok_or("Expected first argument")?;
7 let content = std::fs::read_to_string(path)?;
8
9 pub type Object = HashMap<String, Value>;
10
11 #[derive(Debug)]
12 #[allow(dead_code)]
13 pub enum Value {
14 Object(Object),
15 String(String),
16 Number(String),
17 Boolean(bool),
18 Null,
19 }
20
21 impl Value {
22 pub fn new_empty_object() -> Self {
23 Self::Object(HashMap::new())
24 }
25
26 pub fn set<'a>(&'a mut self, keys: &'a [JSONKey<'a>], value: RootJSONValue<'a>) {
27 if let Value::Object(ref mut obj) = self {
28 if let [last] = keys {
29 let name = match last {
30 JSONKey::Slice(s) => (*s).to_string(),
31 JSONKey::Index(i) => i.to_string(),
32 };
33 let value = match value {
34 RootJSONValue::String(s) => Value::String(s.to_string()),
35 RootJSONValue::Number(n) => Value::Number(n.to_string()),
36 RootJSONValue::Boolean(v) => Value::Boolean(v),
37 RootJSONValue::Null => Value::Null,
38 };
39 let existing = obj.insert(name, value);
40 debug_assert!(existing.is_none());
41 } else if let [first, others @ ..] = keys {
42 let name = match first {
43 JSONKey::Slice(s) => (*s).to_string(),
44 JSONKey::Index(i) => i.to_string(),
45 };
46 obj.entry(name)
47 .or_insert_with(Value::new_empty_object)
48 .set(others, value);
49 } else {
50 unreachable!("empty keys")
51 }
52 } else {
53 unreachable!()
54 }
55 }
56 }
57
58 let mut root = Value::new_empty_object();
59
60 parse(&content, |keys, value| root.set(keys, value))?;
61
62 eprintln!("Parsed: {root:#?}");
63 Ok(())
64}
examples/scan.rs (line 90)
3fn main() {
4 let base = r#"{
5 "name": "ezno",
6 "version": "0.0.14",
7 "description": "A JavaScript compiler and TypeScript checker written in Rust with a focus on static analysis and runtime performance",
8 "license": "MIT",
9 "repository": "https://github.com/kaleidawave/ezno",
10 "main": "./dist/index.mjs",
11 "module": "./dist/index.mjs",
12 "type": "module",
13 "exports": {
14 ".": {
15 "import": "./dist/index.mjs"
16 },
17 "./initialised": {
18 "import": "./dist/initialised.mjs"
19 }
20 },
21 "scripts": {
22 "clean": "rmdir dist && rmdir build",
23 "build": "cargo build --lib --target wasm32-unknown-unknown && npm run bind && npm run build-js",
24 "build-release": "cargo build --lib --release --target wasm32-unknown-unknown && npm run bind-release && npm run build-js",
25 "bind": "wasm-bindgen --out-dir build --target web ../../target/wasm32-unknown-unknown/debug/ezno_lib.wasm",
26 "bind-release": "wasm-bindgen --out-dir build --target web ../../target/wasm32-unknown-unknown/release/ezno_lib.wasm",
27 "build-js": "unbuild && cp ./build/ezno_lib_bg.wasm dist/shared && cp src/cli_node.cjs dist/cli.cjs",
28 "test": "npm run build && npm run run-tests",
29 "run-tests": "node test.mjs && deno run -A test.mjs"
30 },
31 "keywords": [
32 "typescript",
33 "checker",
34 "type-checker",
35 "compiler"
36 ],
37 "files": [
38 "dist"
39 ],
40 "bin": {
41 "ezno": "./dist/cli.mjs"
42 },
43 "author": {
44 "name": "Ben",
45 "email": "kaleidawave@gmail.com",
46 "url": "https://kaleidawave.github.io/"
47 },
48 "funding": {
49 "type": "individual",
50 /*
51 multiline comment
52 */
53 "url": "https://github.com/sponsors/kaleidawave"
54 },
55 "build": {
56 "failOnWarn": false,
57 "entries": [
58 {
59 "builder": "rollup",
60 "input": "./src/index"
61 },
62 {
63 "builder": "rollup",
64 "input": "./src/initialised"
65 },
66 {
67 "builder": "rollup",
68 "input": "./src/cli"
69 }
70 ],
71 // some comment
72 "rollup": {
73 "commonjs": true,
74 "esbuild": {
75 "target": "esnext"
76 }
77 }
78 },
79 "devDependencies": {
80 "unbuild": "^1.1.2"
81 }
82 }"#;
83
84 let content = if let Some(path) = std::env::args().nth(1) {
85 std::fs::read_to_string(path).unwrap()
86 } else {
87 base.to_owned()
88 };
89
90 let result = parse(&content, |keys, value| eprintln!("{keys:?} -> {value:?}"));
91
92 if let Err(JSONParseError { at, reason }) = result {
93 eprintln!("{reason:?} @ {at}");
94 }
95}