Skip to content

Commit

Permalink
Improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
g1mv committed Mar 17, 2024
1 parent 1acc787 commit cb49dae
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
12 changes: 5 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
19 changes: 11 additions & 8 deletions src/json_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<f64> {
if self.json_type != JsonNumber {
None
Expand All @@ -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<i128> {
if self.json_type != JsonNumber {
None
Expand All @@ -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<bool> {
match self.json_type {
JsonTrue => { Some(true) }
Expand All @@ -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<ArrayIterator<JsonItem>> {
if let Some(container) = &self.container {
if let Array(array) = container {
Expand All @@ -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<MapIterator<Key, JsonItem>> {
if let Some(container) = &self.container {
return match container {
Expand Down Expand Up @@ -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) => {
Expand Down
17 changes: 17 additions & 0 deletions src/json_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
/// An enum representing JSON types
/// * `JsonNull` &rarr; null
/// * `JsonTrue`, `JsonFalse` &rarr; true, false
/// * `JsonString` &rarr; a string
/// * `JsonNumber` &rarr; an integer or float
/// * `JsonMap` &rarr; a JSON object
/// * `JsonArray` &rarr; a JSON array
/// * `Empty` &rarr; 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,
Expand Down
8 changes: 2 additions & 6 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand All @@ -41,7 +37,7 @@ impl Key {
Key { slice, hash }
}

///
/// Key text value
pub fn as_str(&self) -> &str {
self.slice.as_str()
}
Expand Down
12 changes: 12 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ fn parse_array(bytes: &[u8], mut index: usize) -> Result<JsonItem, JsonError> {
///
/// # 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<JsonItem, JsonError> {
let bytes = source.as_bytes();
let mut index = 0_usize;
Expand Down

0 comments on commit cb49dae

Please sign in to comment.