Skip to content

Commit 2b8ddc5

Browse files
authored
Merge pull request #34 from b41sh/feat-readme-doc
docs: add more jsonb encoding format descriptions
2 parents b29f2ea + 75eb2b8 commit 2b8ddc5

File tree

2 files changed

+168
-9
lines changed

2 files changed

+168
-9
lines changed

README.md

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,61 @@
77
[crate downloads]: https://img.shields.io/crates/d/jsonb.svg
88

99

10-
11-
`jsonb` is a jsonb implementation written in Rust. It provides a fast, lightweight, and easy-to-use API for working with jsonb data.
10+
`jsonb` is a binary format `JSON` representation inspired by [PostgreSQL](https://www.postgresql.org/docs/current/datatype-json.html) and [CockroachDB](https://www.cockroachlabs.com/docs/stable/jsonb). It provides a fast, lightweight and easy-to-use API for working with `JSON` data.
1211

1312
## Features
1413

15-
- Fast performance: `jsonb` is designed to be highly performant, allowing you to work with large jsonb data sets with ease.
16-
- Easy to use API: `jsonb` provides a simple and intuitive API for working with jsonb data, making it easy to get started.
17-
- Safe and secure: `jsonb` is written in Rust, which provides memory safety and thread safety guarantees, making it a safe choice for handling sensitive data.
18-
- Flexible: `jsonb` supports a wide range of data types and can be used to store complex data structures.
14+
- Good compatibility: `jsonb` fully supports the `JSON` standard and can be used to store complex data structures.
15+
- Fast performance: `jsonb` is designed for high performance, allowing you to work with large `JSON` data sets with ease.
16+
- Easy to use: `jsonb` provides a number of built-in functions to support various operations, and also supports the `JSONPath` syntax for selecting and extracting subset elements.
17+
- Safe and secure: `jsonb` is written in Rust, which provides memory and thread safety guarantees, making it a safe choice for handling sensitive data.
18+
19+
## Encoding format
20+
21+
The `jsonb` encoding format is a tree-like structure. Each node contains a container header, a number of JEntry headers, and nested encoding values.
22+
23+
- 32-bit container header. 3 bits identify the type of value, including `scalar`, `object` and `array`, and 29 bits identify the number of JEntries in the `array` or `object`. The root node of the `jsonb` value is always a container header.
24+
- `scalar` container header: `0x20000000`
25+
- `object` container header: `0x40000000`
26+
- `array` container header: `0x80000000`
27+
- 32-bit JEntry header. 1 bit identifies whether the JEntry stores a length or an offset, 3 bits identify the type of value, including `null`, `string`, `number`, `false`, `true` and `container`, and the remaining 28 bits identify the length or offset of the encoding value.
28+
- `null` JEntry header: `0x00000000`
29+
- `string` JEntry header: `0x10000000`
30+
- `number` JEntry header: `0x20000000`
31+
- `false` JEntry header: `0x30000000`
32+
- `true` JEntry header: `0x40000000`
33+
- `container` JEntry header `0x50000000`
34+
- Encoding value. Different types of JEntry header have different encoding values.
35+
- `null`, `true`, `false`: no encoding value, identified by the JEntry header.
36+
- `string`: a normal UTF-8 string.
37+
- `number`: an encoded number to represent uint64s, int64s and float64s.
38+
- `container`: a nested `json` value with a recursive structure.
1939

40+
#### An encoding example
41+
42+
```text
43+
// JSON value
44+
[false, 10, {"k":"v"}]
45+
46+
// JSONB encoding
47+
0x80000003 array container header (3 JEntries)
48+
0x30000000 false JEntry header (no encoding value)
49+
0x20000002 number JEntry header (encoding value length 2)
50+
0x5000000e container JEntry header (encoding value length 14)
51+
0x500a number encoding value (10)
52+
0x40000001 object container header (1 JEntry)
53+
0x10000001 string key JEntry header (encoding value length 1)
54+
0x10000001 string value JEntry header (encoding value length 1)
55+
0x6b string encoding value ("k")
56+
0x76 string encoding value ("v")
57+
```
2058

21-
## JSONB value struct
59+
## Jsonb value
2260

23-
``` rust
24-
// JSONB value
61+
The `jsonb` value is an enumeration that represents all kinds of `JSON` values and serves as an intermediate for converting other data types to the `jsonb` binary format value.
62+
63+
```rust
64+
// jsonb value
2565
#[derive(Clone, PartialEq, Eq)]
2666
pub enum Value<'a> {
2767
Null,
@@ -33,3 +73,73 @@ pub enum Value<'a> {
3373
}
3474
```
3575

76+
## Built-in functions
77+
78+
`jsonb` implements a number of commonly used built-in functions. Since most functions only focus on a subset of the total value, using container headers and JEntry headers to can efficiently skip over intermediate parts of the `jsonb` value. This avoids time-consuming deserialisation operations and provides very high performance. For more information, see https://docs.rs/jsonb/latest/jsonb/#functions
79+
80+
## SQL/JSONPath
81+
82+
[SQL/JSONPath](https://www.iso.org/standard/67367.html) is a query language used to select and extract a subset of elements from a `jsonb` value.
83+
84+
#### Operators
85+
86+
The following operators have been implemented:
87+
88+
| Operator | Description | Examples |
89+
|--------------------------|--------------------------------------------------------------|--------------------|
90+
| `$` | The root element | `$` |
91+
| `@` | The current element in the filter expression | `$.event?(@ == 1)` |
92+
| `.*` | Selecting all elements in an Object | `$.*` |
93+
| `.<name>` | Selecting element that match the name in an Object | `$.event` |
94+
| `:<name>` | Alias of `.<name>` | `$:event` |
95+
| `["<name>"]` | Alias of `.<name>` | `$["event"]` |
96+
| `[*]` | Selecting all elements in an Array | `$[*]` |
97+
| `[<pos>, ..]` | Selecting 0-based `n-th` elements in an Array | `$[1, 2]` |
98+
| `[last - <pos>, ..]` | Selecting `n-th` element before the last element in an Array | `$[0, last - 1]` |
99+
| `[<pos1> to <pos2>, ..]` | Selecting all elements of a range in an Array | `$[1 to last - 2]` |
100+
| `?(<expr>)` | Selecting all elements that matched the filter expression | `$?(@.price < 10)` |
101+
102+
## Examples
103+
104+
```rust
105+
fn main() {
106+
let json = r#"
107+
{
108+
"name":"Fred",
109+
"phones":[
110+
{
111+
"type":"home",
112+
"number":3720453
113+
},
114+
{
115+
"type": "work",
116+
"number":5062051
117+
}
118+
]
119+
}"#;
120+
121+
let path = r#"$.phones[*]?(@.number == 3720453)"#;
122+
123+
// parse JSON string to jsonb value
124+
let value = jsonb::parse_value(json.as_bytes()).unwrap();
125+
// encode jsonb value to jsonb binary value
126+
let jsonb = value.to_vec();
127+
// parse JSONPath string
128+
let json_path = jsonb::jsonpath::parse_json_path(path.as_bytes()).unwrap();
129+
// select subset value from jsonb binary value
130+
let mut sub_jsonb = Vec::new();
131+
let mut sub_offsets = Vec::new();
132+
jsonb::get_by_path(&jsonb, json_path, &mut sub_jsonb, &mut sub_offsets);
133+
134+
// value={"number":3720453,"type":"home"}
135+
println!("value={}", jsonb::to_string(&sub_jsonb));
136+
}
137+
```
138+
139+
## Contributing
140+
141+
`jsonb` is an open source project and all kinds of contributions are welcome! You can help with ideas, code or documentation.
142+
143+
## License
144+
145+
Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)

src/lib.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,55 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
//! `jsonb` is a binary format `JSON` representation inspired by [PostgreSQL](https://www.postgresql.org/docs/current/datatype-json.html) and [CockroachDB](https://www.cockroachlabs.com/docs/stable/jsonb). It provides a fast, lightweight and easy-to-use API for working with `JSON` data.
16+
//!
17+
//! ## Features
18+
//!
19+
//! - Good compatibility: `jsonb` fully supports the `JSON` standard and can be used to store complex data structures.
20+
//! - Fast performance: `jsonb` is designed for high performance, allowing you to work with large `JSON` data sets with ease.
21+
//! - Easy to use: `jsonb` provides a number of built-in functions to support various operations, and also supports the `JSONPath` syntax for selecting and extracting subset elements.
22+
//! - Safe and secure: `jsonb` is written in Rust, which provides memory and thread safety guarantees, making it a safe choice for handling sensitive data.
23+
//!
24+
//! ## Encoding format
25+
//!
26+
//! The `jsonb` encoding format is a tree-like structure. Each node contains a container header, a number of JEntry headers, and nested encoding values.
27+
//!
28+
//! - 32-bit container header. 3 bits identify the type of value, including `scalar`, `object` and `array`, and 29 bits identify the number of JEntries in the `array` or `object`. The root node of the `jsonb` value is always a container header.
29+
//! - `scalar` container header: `0x20000000`
30+
//! - `object` container header: `0x40000000`
31+
//! - `array` container header: `0x80000000`
32+
//! - 32-bit JEntry header. 1 bit identifies whether the JEntry stores a length or an offset, 3 bits identify the type of value, including `null`, `string`, `number`, `false`, `true` and `container`, and the remaining 28 bits identify the length or offset of the encoding value.
33+
//! - `null` JEntry header: `0x00000000`
34+
//! - `string` JEntry header: `0x10000000`
35+
//! - `number` JEntry header: `0x20000000`
36+
//! - `false` JEntry header: `0x30000000`
37+
//! - `true` JEntry header: `0x40000000`
38+
//! - `container` JEntry header `0x50000000`
39+
//! - Encoding value. Different types of JEntry header have different encoding values.
40+
//! - `null`, `true`, `false`: no encoding value, identified by the JEntry header.
41+
//! - `string`: a normal UTF-8 string.
42+
//! - `number`: an encoded number to represent uint64s, int64s and float64s.
43+
//! - `container`: a nested `json` value with a recursive structure.
44+
//!
45+
//! #### An encoding example
46+
//!
47+
//! ```text
48+
//! // JSON value
49+
//! [false, 10, {"k":"v"}]
50+
//!
51+
//! // JSONB encoding
52+
//! 0x80000003 array container header (3 JEntries)
53+
//! 0x30000000 false JEntry header (no encoding value)
54+
//! 0x20000002 number JEntry header (encoding value length 2)
55+
//! 0x5000000e container JEntry header (encoding value length 14)
56+
//! 0x500a number encoding value (10)
57+
//! 0x40000001 object container header (1 JEntry)
58+
//! 0x10000001 string key JEntry header (encoding value length 1)
59+
//! 0x10000001 string value JEntry header (encoding value length 1)
60+
//! 0x6b string encoding value ("k")
61+
//! 0x76 string encoding value ("v")
62+
//! ```
63+
1564
#![allow(clippy::uninlined_format_args)]
1665

1766
mod constants;

0 commit comments

Comments
 (0)