From cb49dae417960476e2d1c5f2f8a8809382b6453a Mon Sep 17 00:00:00 2001 From: Guillaume <3772944+g1mv@users.noreply.github.com> Date: Sun, 17 Mar 2024 13:19:35 +0100 Subject: [PATCH] Improve docs --- Cargo.toml | 2 +- readme.md | 12 +++++------- src/json_item.rs | 19 +++++++++++-------- src/json_type.rs | 17 +++++++++++++++++ src/key.rs | 8 ++------ src/lib.rs | 12 ++++++++++++ 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f96be4f..32d30a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jsonic" -version = "0.2.11" +version = "0.2.12" edition = "2021" description = "Fast, small JSON parsing library for rust with no dependencies" license = "MIT OR Apache-2.0" diff --git a/readme.md b/readme.md index 43da666..3d63566 100644 --- a/readme.md +++ b/readme.md @@ -8,10 +8,8 @@ Fast, small JSON parsing library for rust with no dependencies **jsonic** is a JSON parser. It aims at providing high-speed extraction of JSON data. It does not convert JSON to structs at this stage. -It can be easily used as a drop-in replacement for other libraries, due to its simple code semantics. - ### Performance -Blazing-fast JSON parsing is made possible by some of the following design choices: +Here are some of the design choices for this library: * small-footprint data structures to speedup memory/cache access * object containers with hybrid data structures, using arrays to store low numbers of key/value pairs, and binary tree maps otherwise @@ -28,17 +26,17 @@ fn main() { let json = "{\"jsonic\": \"Fast, small JSON parsing library for rust with no dependencies\"}"; match jsonic::parse(json) { - Some(parsed) => { println!("Describe jsonic? {}", parsed["jsonic"].as_str()); } - Err(error) => { eprintln!("{}", error.to_string()); } + Ok(parsed) => { println!("Describe jsonic? {:?}", parsed["jsonic"].as_str()); } + Err(error) => { eprintln!("{}", error); } } } ``` ### Benchmark -Benchmarking is provided via ```cargo bench```. It compares **jsonic**'s parsing speed with other JSON parsing engines written in rust. +To get an overview of **jsonic**'s parsing performance compared to other JSON parsing engines written in rust, use ```cargo bench```. -Here is a sample run on an Apple iMac M1, 8GB RAM, macOS Sonoma 14.4 (23E214): +Here is a sample run on an Apple iMac M1, 8GB RAM, macOS Sonoma: ```shell Running benches/json-rust.rs (target/release/deps/json_rust-0d2370885fb224f4) diff --git a/src/json_item.rs b/src/json_item.rs index 774d20a..e80edb9 100644 --- a/src/json_item.rs +++ b/src/json_item.rs @@ -52,7 +52,8 @@ impl JsonItem { } /// Returns &str value of item. - /// This only returns None if the item is non-existent. + /// This only returns `None` if the item is non-existent. + /// In all other cases (even for `null`, `true`, `false`, numbers, arrays and objects), the text content of the item is returned, as extracted from the source data. pub fn as_str(&self) -> Option<&str> { if self.json_type == Empty { None @@ -61,7 +62,7 @@ impl JsonItem { } } - /// Tries to convert item to f64. If the conversion fails, returns None. + /// Tries to convert item to `f64`. If the conversion fails, returns `None`. pub fn as_f64(&self) -> Option { if self.json_type != JsonNumber { None @@ -70,8 +71,8 @@ impl JsonItem { } } - /// Tries to convert item to an i128 integer. If the conversion fails, returns None. - /// Resulting i128 can then be easily converted to other integer types using "as". + /// Tries to convert item to an `i128` integer. If the conversion fails, returns `None`. + /// Resulting `i128` can then be converted to other integer types as required. pub fn as_i128(&self) -> Option { if self.json_type != JsonNumber { None @@ -80,7 +81,7 @@ impl JsonItem { } } - /// Tries to convert item to a bool. If the conversion fails, returns None. + /// Tries to convert item to a `bool`. If the conversion fails, returns `None`. pub fn as_bool(&self) -> Option { match self.json_type { JsonTrue => { Some(true) } @@ -104,7 +105,8 @@ impl JsonItem { &self.json_type } - /// If the item is an array, returns an iterator over array elements. Otherwise, returns None. + /// If the item is an array, returns an iterator over array elements. If the array is empty (`[]`), an empty iterator is returned. + /// Otherwise, returns `None`. pub fn elements(&self) -> Option> { if let Some(container) = &self.container { if let Array(array) = container { @@ -118,7 +120,8 @@ impl JsonItem { None } - /// If the item is an object, returns an iterator over object entries. Otherwise, returns None. + /// If the item is an object, returns an iterator over object entries. If the object contains no entries (`{}`), an empty iterator is returned. + /// Otherwise, returns `None`. pub fn entries(&self) -> Option> { if let Some(container) = &self.container { return match container { @@ -152,7 +155,7 @@ impl Index<&str> for JsonItem { type Output = JsonItem; fn index(&self, key: &str) -> &Self::Output { - let key = Key::from_slice(Slice::from_str(key)); + let key = Key::from_str(key); if let Some(container) = &self.container { match container { MapVec(map) => { diff --git a/src/json_type.rs b/src/json_type.rs index 340f112..bb161ed 100644 --- a/src/json_type.rs +++ b/src/json_type.rs @@ -1,4 +1,21 @@ /// An enum representing JSON types +/// * `JsonNull` → null +/// * `JsonTrue`, `JsonFalse` → true, false +/// * `JsonString` → a string +/// * `JsonNumber` → an integer or float +/// * `JsonMap` → a JSON object +/// * `JsonArray` → a JSON array +/// * `Empty` → Element not found. See code below. +/// +/// ```rust +/// use jsonic::json_item::JsonItem; +/// use jsonic::json_type::JsonType::Empty; +/// +/// let json = "{\"a\":\"b\"}"; +/// +/// if let Ok(parsed) = jsonic::parse(json) { +/// assert!(parsed["c"].get_type() == &Empty); +/// } #[derive(PartialEq, Debug)] pub enum JsonType { JsonNull, diff --git a/src/key.rs b/src/key.rs index 49a5317..e23447c 100644 --- a/src/key.rs +++ b/src/key.rs @@ -28,11 +28,7 @@ pub struct Key { } impl Key { - /// Create a key using &str - /// - /// # Arguments - /// * `source` - Key id - pub fn from_str(source: &str) -> Self { + pub(crate) fn from_str(source: &str) -> Self { Self::from_slice(Slice::from_str(source)) } @@ -41,7 +37,7 @@ impl Key { Key { slice, hash } } - /// + /// Key text value pub fn as_str(&self) -> &str { self.slice.as_str() } diff --git a/src/lib.rs b/src/lib.rs index d0547b5..7a2433f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -209,6 +209,18 @@ fn parse_array(bytes: &[u8], mut index: usize) -> Result { /// /// # Arguments /// * `source` - Text content to be parsed +/// +/// # Example +/// +/// ```rust +/// fn main() { +/// let json = "{\"jsonic\": \"Fast, small JSON parsing library for rust with no dependencies\"}"; +/// +/// match jsonic::parse(json) { +/// Ok(parsed) => { println!("Describe jsonic? {:?}", parsed["jsonic"].as_str()); } +/// Err(error) => { eprintln!("{}", error); } +/// } +/// } pub fn parse(source: &str) -> Result { let bytes = source.as_bytes(); let mut index = 0_usize;