Function simple_json_parser::parse
source · pub fn parse<'a>(
on: &'a str,
cb: impl for<'b> FnMut(&'b [JSONKey<'a>], RootJSONValue<'a>)
) -> Result<(), JSONParseError>
Expand description
If you want to return early (not parse the whole input) use parse_with_exit_signal
§Errors
Returns an error if it tries to parse invalid JSON input
Examples found in repository?
examples/to_object_unsafe.rs (lines 30-72)
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
fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = std::env::args().nth(1).ok_or("Expected first argument")?;
let content = std::fs::read_to_string(path)?;
pub type Object = HashMap<String, Value>;
#[derive(Debug)]
pub enum Value {
Object(Object),
String(String),
Number(String),
Boolean(bool),
Null,
}
impl Value {
pub fn new_empty_object() -> Self {
Self::Object(HashMap::new())
}
}
let mut root = Object::new();
let _res = parse(&content, |keys, value| {
let [path @ .., end] = keys else {
unreachable!("empty key change")
};
let pointer = &mut root;
let mut to_add_to: *mut Object = pointer;
for key in path {
let name = match key {
JSONKey::Slice(s) => (*s).to_string(),
JSONKey::Index(i) => i.to_string(),
};
if let Some(Value::Object(ref mut obj)) =
unsafe { (to_add_to.as_mut().unwrap()).get_mut(&name) }
{
to_add_to = obj;
} else {
let value = unsafe {
(to_add_to.as_mut().unwrap())
.entry(name)
.or_insert_with(Value::new_empty_object)
};
if let Value::Object(ref mut obj) = value {
to_add_to = obj;
}
}
}
let name = match end {
JSONKey::Slice(s) => (*s).to_string(),
JSONKey::Index(i) => i.to_string(),
};
let value = match value {
RootJSONValue::String(s) => Value::String(s.to_string()),
RootJSONValue::Number(n) => Value::Number(n.to_string()),
RootJSONValue::True => Value::Boolean(true),
RootJSONValue::False => Value::Boolean(false),
RootJSONValue::Null => Value::Null,
};
unsafe {
(to_add_to.as_mut().unwrap()).insert(name, value);
}
});
eprintln!("Parsed: {root:#?}");
Ok(())
}
More examples
examples/to_object.rs (line 60)
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
fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = std::env::args().nth(1).ok_or("Expected first argument")?;
let content = std::fs::read_to_string(path)?;
pub type Object = HashMap<String, Value>;
#[derive(Debug)]
pub enum Value {
Object(Object),
String(String),
Number(String),
Boolean(bool),
Null,
}
impl Value {
pub fn new_empty_object() -> Self {
Self::Object(HashMap::new())
}
pub fn set<'a>(&'a mut self, keys: &'a [JSONKey<'a>], value: RootJSONValue<'a>) {
if let Value::Object(ref mut obj) = self {
if let [last] = keys {
let name = match last {
JSONKey::Slice(s) => (*s).to_string(),
JSONKey::Index(i) => i.to_string(),
};
let value = match value {
RootJSONValue::String(s) => Value::String(s.to_string()),
RootJSONValue::Number(n) => Value::Number(n.to_string()),
RootJSONValue::True => Value::Boolean(true),
RootJSONValue::False => Value::Boolean(false),
RootJSONValue::Null => Value::Null,
};
let existing = obj.insert(name, value);
debug_assert!(existing.is_none());
} else if let [first, others @ ..] = keys {
let name = match first {
JSONKey::Slice(s) => (*s).to_string(),
JSONKey::Index(i) => i.to_string(),
};
obj.entry(name)
.or_insert_with(Value::new_empty_object)
.set(others, value);
} else {
unreachable!("empty keys")
}
} else {
unreachable!()
}
}
}
let mut root = Value::new_empty_object();
parse(&content, |keys, value| root.set(keys, value))?;
eprintln!("Parsed: {root:#?}");
Ok(())
}
examples/scan.rs (line 90)
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95
fn main() {
let base = r#"{
"name": "ezno",
"version": "0.0.14",
"description": "A JavaScript compiler and TypeScript checker written in Rust with a focus on static analysis and runtime performance",
"license": "MIT",
"repository": "https://github.com/kaleidawave/ezno",
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"type": "module",
"exports": {
".": {
"import": "./dist/index.mjs"
},
"./initialised": {
"import": "./dist/initialised.mjs"
}
},
"scripts": {
"clean": "rmdir dist && rmdir build",
"build": "cargo build --lib --target wasm32-unknown-unknown && npm run bind && npm run build-js",
"build-release": "cargo build --lib --release --target wasm32-unknown-unknown && npm run bind-release && npm run build-js",
"bind": "wasm-bindgen --out-dir build --target web ../../target/wasm32-unknown-unknown/debug/ezno_lib.wasm",
"bind-release": "wasm-bindgen --out-dir build --target web ../../target/wasm32-unknown-unknown/release/ezno_lib.wasm",
"build-js": "unbuild && cp ./build/ezno_lib_bg.wasm dist/shared && cp src/cli_node.cjs dist/cli.cjs",
"test": "npm run build && npm run run-tests",
"run-tests": "node test.mjs && deno run -A test.mjs"
},
"keywords": [
"typescript",
"checker",
"type-checker",
"compiler"
],
"files": [
"dist"
],
"bin": {
"ezno": "./dist/cli.mjs"
},
"author": {
"name": "Ben",
"email": "kaleidawave@gmail.com",
"url": "https://kaleidawave.github.io/"
},
"funding": {
"type": "individual",
/*
multiline comment
*/
"url": "https://github.com/sponsors/kaleidawave"
},
"build": {
"failOnWarn": false,
"entries": [
{
"builder": "rollup",
"input": "./src/index"
},
{
"builder": "rollup",
"input": "./src/initialised"
},
{
"builder": "rollup",
"input": "./src/cli"
}
],
// some comment
"rollup": {
"commonjs": true,
"esbuild": {
"target": "esnext"
}
}
},
"devDependencies": {
"unbuild": "^1.1.2"
}
}"#;
let content = if let Some(path) = std::env::args().nth(1) {
std::fs::read_to_string(path).unwrap()
} else {
base.to_owned()
};
let result = parse(&content, |keys, value| eprintln!("{keys:?} -> {value:?}"));
if let Err(JSONParseError { at, reason }) = result {
eprintln!("{reason:?} @ {at}");
}
}