Function parse

Source
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
Hide additional 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}