A few days ago I released version 0.2.0 of my low-level JSON library called 'Struson'. It is still experimental, but any feedback and suggestions regarding API and implementation are welcome!
Compared to version 0.1.0 the new version 0.2.0 adds methods for reading values (JSON strings, numbers and member names) as borrowed strings. This now allows reading JSON data without any additional allocations in many cases.
Examples
-
Reading:
let json = r#" { "first": 1.23e4, "second": [ true, "value" ] } "#; let mut json_reader = JsonStreamReader::new(json.as_bytes()); json_reader.begin_object()?; assert_eq!(json_reader.next_name()?, "first"); assert_eq!(json_reader.next_number_as_str()?, "1.23e4"); assert_eq!(json_reader.next_name()?, "second"); json_reader.begin_array()?; assert_eq!(json_reader.next_bool()?, true); assert_eq!(json_reader.next_str()?, "value"); json_reader.end_array()?; json_reader.end_object()?; json_reader.consume_trailing_whitespace()?;
-
Writing:
let mut writer = Vec::<u8>::new(); let mut json_writer = JsonStreamWriter::new_custom( &mut writer, WriterSettings { pretty_print: true, ..Default::default() }, ); json_writer.begin_object()?; json_writer.name("first")?; json_writer.number_value(123)?; json_writer.name("second")?; json_writer.begin_array()?; json_writer.bool_value(true)?; json_writer.string_value("value")?; json_writer.end_array()?; json_writer.end_object()?; json_writer.finish_document()?; assert_eq!( String::from_utf8(writer)?, "{\n \"first\": 123,\n \"second\": [\n true,\n \"value\"\n ]\n}" );
-
Seeking and transferring from reader to writer:
let json = r#" { "first": 1.23e4, "second": [ true, "value" ] } "#; let mut json_reader = JsonStreamReader::new(json.as_bytes()); let mut writer = Vec::<u8>::new(); let mut json_writer = JsonStreamWriter::new(&mut writer); // Skip to path in JSON data, here to JSON string `"value"` json_reader.seek_to(&json_path!["second", 1])?; // Optionally write enclosing data for transferred value json_writer.begin_object()?; json_writer.name("transferred")?; json_reader.transfer_to(&mut json_writer)?; // Finish reading json_reader.skip_to_top_level()?; json_reader.consume_trailing_whitespace()?; json_writer.end_object()?; json_writer.finish_document()?; assert_eq!(String::from_utf8(writer)?, "{\"transferred\":\"value\"}");
-
Serde interoperability (requires
serde
feature):let json = r#" { "outer": { "a": 1, "b": "value" } } "#; #[derive(serde::Deserialize, PartialEq, Debug)] struct MyStruct { a: u32, b: String, } let mut json_reader = JsonStreamReader::new(json.as_bytes()); json_reader.seek_to(&json_path!["outer"])?; let deserialized: MyStruct = json_reader.deserialize_next()?; assert_eq!( deserialized, MyStruct { a: 1, b: "value".to_owned() } ); // Finish reading json_reader.skip_to_top_level()?; json_reader.consume_trailing_whitespace()?;