importcjj/rust-ajson

Read JSON values quickly - Rust JSON Parser

AJSON get json value with specified path, such as project

A-JSON

change name to AJSON, see issue

Inspiration comes from gjson in golang

Installation

Add it to your Cargo.toml file:

[dependencies]
ajson = "0.2"

Then add it to your code:

extern crate ajson;

Todo

  • Add documentation
  • Follow api-guidelines
  • Update benchmark
  • Optimize

A simple example

AJSON get json value with specified path, such as project.name or project.version. When the path matches, it returns immediately!

let data = r#"
{
  "project": {
    "name": "ajson",
    "maintainer": "importcjj",
    "version": 0.1,
    "rusts": ["stable", "nightly"]
  }
}
"#;

let name = ajson::get(data, "project.name").unwrap();
println!("{}", name.as_str()); // ajson

Path Syntax

JSON example

{
    "name": {"first": "Tom", "last": "Anderson"},
    "age":37,
    "children": ["Sara","Alex","Jack"],
    "fav.movie": "Deer Hunter",
    "friends": [
        {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
        {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
        {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
    ]
}

basic

Below is a quick overview of the path syntax, for more complete information please check out GJSON Syntax.

A path is a series of keys separated by a dot. A key may contain special wildcard characters '*' and '?'. To access an array value use the index as the key. To get the number of elements in an array or to access a child path, use the '#' character. The dot and wildcard characters can be escaped with ''.

name.last        >> "Anderson"
age              >> 37
children         >> ["Sara","Alex","Jack"]
children.#       >> 3
children.1       >> "Alex"
child*.2         >> "Jack"
c?ildren.0       >> "Sara"
fav\.movie       >> "Deer Hunter"
friends.#.first  >> ["Dale","Roger","Jane"]
friends.1.last   >> "Craig"

Escape character

Special purpose characters, such as ., *, and ? can be escaped with .

fav\.movie             "Deer Hunter"

Arrays

The # character allows for digging into JSON Arrays.To get the length of an array you'll just use the # all by itself.

friends.#              3
friends.#.age         [44,68,47]

queries

You can also query an array for the first match by using #(...), or find all matches with #(...)#. Queries support the ==, !=, <, <=, >, >= comparison operators and the simple pattern matching % (like) and !% (not like) operators.

friends.#(last=="Murphy").first   >> "Dale"
friends.#(last=="Murphy")#.first  >> ["Dale","Jane"]
friends.#(age>45)#.last           >> ["Craig","Murphy"]
friends.#(first%"D*").last        >> "Murphy"
friends.#(nets.#(=="fb"))#.first  >> ["Dale","Roger"]

construct

Basically, you can use selectors to assemble whatever you want, and of course, the result is still a json ;)

{name.first,age,"murphys":friends.#(last="Murphy")#.first}
[name.first,age,children.0]
ajson::get(json, "name.[first,last]").unwrap().to_vec();
ajson::get(json, "name.first").unwrap(); 
ajson::get(json, "name.last").unwrap();

Value

Value types.

enum Value {
    String(String),
    Number(Number),
    Object(String),
    Array(String),
    Boolean(bool),
    Null,
}

Value has a number of methods that meet your different needs.

value.get(&str) -> Option<Value>
value.as_str() -> &str
value.to_u64() -> u64
value.to_i64() -> i64
value.to_f64() -> f64
value.to_bool() -> bool
value.to_vec() -> Vec<Value>
value.to_object() -> HashMap<String, Value>
value.is_number() -> bool
value.is_string() -> bool
value.is_bool() -> bool
value.is_object() -> bool
value.is_array() -> bool
value.is_null() -> bool

get or parse?

Parse needs to read a complete json element, but get returns the result immediately, so get is recommended if you want to simply get a value

io::Read

Not only string, AJSON also can parse JSON from io::Read.

use std::fs::File;

let f = file::Open("path/to/json").unwrap();
let json = ajson::parse_from_read(f).unwrap();
let value = json.get("a.b").unwrap();
println!("{}", value.as_str());

Validate

AJSON can help you get the desired value from flawed JSON, but it's worth being more careful because of its looseness.

be careful!!!

Maybe need a validate function 🤔

Performance

$ cargo bench

  • ajson
  • serde_json
  • rust-json
ajson benchmark         time:   [6.7000 us 6.8023 us 6.9081 us]                             
                        change: [-1.8368% -0.4152% +1.0466%] (p = 0.58 > 0.05)
                        No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

serde_json benchmark    time:   [48.196 us 48.543 us 48.947 us]                                  
                        change: [+2.9073% +4.4909% +6.3532%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) high mild
  2 (2.00%) high severe

json-rust benchmark     time:   [24.540 us 24.773 us 25.061 us]                                 
                        change: [+4.8288% +6.0452% +7.4633%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) high mild
  1 (1.00%) high severe
  • MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)
  • 2.7 GHz Intel Core i7
  • 16 GB 2133 MHz LPDDR3

problems

AJSON has just been finished, there may be some bugs and shortcomings, please feel free to issue. Also, Rust is a new language for me, and maybe ajson isn't rust enough, so I hope you have some suggestions.

License

MIT License.

Issues

Collection of the latest Issues

rignatev

rignatev

Todo
Comment Icon2

Hello! First of all, thanks for this project.

Could you please add conditions operators AND, OR for using multiple conditions in one query?

For example:

Information - Updated May 20, 2022

Stars: 85
Forks: 9
Issues: 2

Serde is a framework for serializing and deserializing Rust data structures efficiently and generically

Rust Greatest JSON weapon is Serde with over 4.4K stars on github and a massive developer community. This is considered a core Rust library for every developer to learn in BRC's opinion

Serde is a framework for serializing and deserializing Rust data structures efficiently and generically

Rust 버전 JsonPath 구현으로 Webassembly와 Javascript에서도 유사한 API 인터페이스를 제공 한다

JsonPath 구현으로 Webassembly와 Javascript에서도 유사한 API 인터페이스를 제공 한다

Rust 버전 JsonPath 구현으로 Webassembly와 Javascript에서도 유사한 API 인터페이스를 제공 한다

SIMD JSON for Rust  

Rust port of extremely fast serde compatibility

SIMD JSON for Rust  

JSON-E Rust data-struct paramter crate for lightweight embedded content with objects and much more

What makes JSON-e unique is that it extensive documentation and ease of use

JSON-E Rust data-struct paramter crate for lightweight embedded content with objects and much more
JSON

111

A Rust JSON5 serializer and deserializer which speaks Serde

Deserialize a JSON5 string with from_str

A Rust JSON5 serializer and deserializer which speaks Serde

Rust JSON Parser Benchmark

Download and Generate JSON Data

Rust JSON Parser Benchmark

Rust actix json request example

Send a json request to actix, and parse it

Rust actix json request example
JSON

140

json_typegen - Rust types from JSON samples

json_typegen is a collection of tools for generating types from

json_typegen - Rust types from JSON samples

Rust JSON parsing benchmarks

This project aims to provide benchmarks to show how various JSON-parsing libraries in the Rust programming language perform at various JSON-parsing tasks

Rust JSON parsing benchmarks

A tiny command line tool written in rust to print json data as a formatted...

A tiny command line tool written in rust to print json data as a formatted table

A tiny command line tool written in rust to print json data as a formatted...

A Rust implementation of the JSON-RPC 2

A Rust implementation of the serde) for JSON-RPC

A Rust implementation of the JSON-RPC 2
Facebook Instagram Twitter GitHub Dribbble
Privacy