• Stars
    star
    104
  • Rank 330,604 (Top 7 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 5 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rust port of gjson,get JSON value by dotpath syntax

A-JSON

Read JSON values quickly - Rust JSON Parser

change name to AJSON, see issue

Inspiration comes from gjson in golang

Installation

Add it to your Cargo.toml file:

[dependencies]
ajson = "0.3"

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().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().unwrap().to_vec();
ajson::get(json, "name.first").unwrap().unwrap(); 
ajson::get(json, "name.last").unwrap().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.as_u64() -> u64
value.as_i64() -> i64
value.as_f64() -> f64
value.as_bool() -> bool
value.as_vec() -> Vec<Value>
value.as_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

Performance

$ cargo bench

ajson benchmark         time:   [2.0816 us 2.0865 us 2.0917 us]                             
                        change: [+0.6172% +0.9272% +1.2430%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 11 outliers among 100 measurements (11.00%)
  7 (7.00%) high mild
  4 (4.00%) high severe

serde_json benchmark    time:   [23.033 us 23.076 us 23.119 us]                                  
                        change: [-0.7185% -0.3455% +0.0230%] (p = 0.07 > 0.05)
                        No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
  6 (6.00%) high mild
  1 (1.00%) high severe

json-rust benchmark     time:   [12.225 us 12.289 us 12.381 us]                                 
                        change: [-2.6200% -1.1789% +0.8442%] (p = 0.19 > 0.05)
                        No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
  5 (5.00%) high mild
  4 (4.00%) high severe

ajson selector          time:   [1.1523 us 1.1561 us 1.1604 us]                            
                        change: [+0.1567% +0.7278% +1.2945%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

ajson multi query       time:   [559.19 ns 559.96 ns 560.77 ns]                               
                        change: [-1.4268% -1.0380% -0.6698%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

serde derive            time:   [4.5301 us 4.5403 us 4.5507 us]                          
                        change: [-2.3423% -1.9438% -1.5697%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild

serde derive multi query                        
                        time:   [956.86 ns 962.64 ns 970.05 ns]
                        change: [-1.7069% -1.0299% -0.2924%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
  3 (3.00%) high mild
  6 (6.00%) high severe

nom json bench          time:   [2.9468 us 2.9515 us 2.9566 us]
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) high mild
  1 (1.00%) high severe
  • MacBook Pro (14-inch, 2021)
  • Apple M1 Pro
  • 16 GB

License

MIT License.

More Repositories

1

sensitive

敏感词查找,验证,过滤和替换 🤓 FindAll, Validate, Filter and Replace words.
Go
630
star
2

mobc

A generic connection pool for Rust with async/await support
Rust
283
star
3

rust-miniproxy

手把手教你用Rust写代理, 代码已完成, 文章不定期更新
JavaScript
154
star
4

nipper

A Rust crate for manipulating HTML with CSS selectors
Rust
121
star
5

gkd-rs

A multi-connections TCP accelerator, written in Rust
Rust
26
star
6

trie-go

The golang implementation of trie tree.
Go
24
star
7

danmu.go

基于golang的命令行形式的直播网站(斗鱼)的弹幕浏览
Go
18
star
8

react-affix

A simple react affix component(Deprecated, use sticky instead)
JavaScript
15
star
9

mobc-redis

Redis support for the mobc connection pool
Rust
12
star
10

notes

My notes
10
star
11

mobc-postgres

Rust
9
star
12

neighbor

基于geohash和mysql实现的附近的人
Go
6
star
13

Posts

📫 Posts is a Python library for send mail easily.
Python
5
star
14

douyu

Crawler For DouyuTv Statistics
Python
4
star
15

yake

Pelican theme.
HTML
4
star
16

tiresias

simple demos for learning scarpy
Python
2
star
17

sparta

Douyu Statistic Backend
JavaScript
2
star
18

comethandler

🔫 helps the server which is builded with golang to push messages to the http clients easily.
Go
2
star
19

tide-demo

Rust
1
star
20

hackathon-2015

Eleme Hackathon 2015
Java
1
star
21

wisburg-terminal

JavaScript
1
star
22

flask_restful_doc

Generate api docs for flask restful resource
Python
1
star
23

bomd-server

base on markdown. a lightweight blog framework which id managed in local
CSS
1
star
24

noname

Go
1
star
25

remote-shortcuts

通过手机使用快捷键操作windows程序
Rust
1
star
26

init-react-webpack-project

A simple and small python2 script that can help you to init a react & webpack project.
Python
1
star