https://github.com/dahomey-technologies/cborpath-rs
CborPath engine written in Rust.
https://github.com/dahomey-technologies/cborpath-rs
cbor cborpath rust
Last synced: 3 months ago
JSON representation
CborPath engine written in Rust.
- Host: GitHub
- URL: https://github.com/dahomey-technologies/cborpath-rs
- Owner: dahomey-technologies
- License: mit
- Created: 2023-01-25T00:46:04.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-04-07T19:59:30.000Z (over 2 years ago)
- Last Synced: 2025-06-13T09:45:31.930Z (4 months ago)
- Topics: cbor, cborpath, rust
- Language: Rust
- Homepage:
- Size: 122 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://crates.io/crates/cborpath)
[](https://docs.rs/cborpath)
[](https://github.com/dahomey-technologies/cborpath-rs/actions/workflows/compile_and_test.yml)
[](LICENSE)# cborpath-rs
cborpath is a CBORPath engine written in Rust.# CBORPath
CBORPath is an adaptation of JSONPath to [CBOR](https://www.rfc-editor.org/rfc/rfc8949.html)
based on the [JSONPath Internet Draft](https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-09.html)## Syntax summary
### Path
A `path` expression is a `CBOR Array` which, when applied to a `CBOR` value, the
*argument*, selects zero or more nodes of the argument and output these nodes as a nodelist.
A `path` always begins by an identifier
* a root identifier (`$`) for absolute paths,
* a current node identifier (`@`) for relative paths. relative path are always used in a filter context.
A `path` is then followed by one or more `segments`.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| `["$", ]` | an absolute path composed by an array of segments
and which always begins by a root identifier (`$`) |
| `["@", ]` | a relative path composed by an array of segments
and which always begins by a current node identifier (`@`) |### Segment
`Segments` apply one or more `selectors` to an input value and concatenate the results into a single nodelist.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| `[]` | a `child segment`, composed by one ore more `selectors` |
| `` | shortcut for a `child segment`, composed by a unique `selector` |
| `{"..": []}` | a `descendant segment`, composed by one ore more `selectors` |
| `{"..": }` | shortcut for a `descendant segment`, composed by a unique `selector` |### Selector
A selector produces a nodelist consisting of zero or more children of the input value.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| ``
``
``
``
``
`` | `key selector`: selects a child of a CBOR Map based on the child key |
| `{"*": 1}` | `wildcard selector`: selects all children of a node |
| `{"#": }` | `index selector`: selects an indexed child of an array (from 0) |
| `{":": [, , ]}` | `array slice selector`: selects a subset of the elements of an array
(between `start` and `end` with a `step`) |
| `{"?": }` | `filter selector`: selects particular children using a boolean expression |### Boolean expression
A boolean expression returns `true` or `false` and is used by a `filter selector` to filter array elements or map items.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| `{"&&": [, ]}` | logical `AND` |
| `{"\|\|": [, ]}` | logical `OR` |
| `{"!": }` | logical `NOT` |
| `{"<=": [, ]}` | comparison `lesser than or equal |
| `{"<": [, ]}` | comparison `lesser than` |
| `{"==": [, ]}` | comparison `equal` |
| `{"!=": [, ]}` | comparison `not equal` |
| `{">": [, ]}` | comparison `greater than` |
| `{">=": [, ]}` | comparison `greater than or equal` |
| `{"match": [, ]}` | match function to compute a regular expression full match.
returns a boolean |
| `{"search": [, ]}` | length function to compute a regular expression substring match.
returns a boolean |### Comparable
A `comparable` is an operand of a `filter` comparison or an argument of a function.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| ``
``
``
``
``
`` | a `CBOR` value |
| `["$", ]`
`["@", ]` | a singular path (path which procudes a nodelist containing at most one node) |
| `{"length": }` | length function to compute the length of a value.
returns an unsigned integer |
| `{"count": }` | count function to compute the number of nodes in a path.
returns an unsigned integer |
| `{"value": }` | value function to get the number of a single node path.
returns a `CBOR` value |### Singular Segment
A `singular segment` produces a nodelist containing at most one node.| Syntax | Description |
|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| ``
``
``
``
``
`` | `key selector`: selects a child of a CBOR Map based on the child key |
| `{"#": }` | `index selector`: selects an indexed child of an array (from 0) |## Examples
This section is informative. It provides examples of CBORPath expressions.
The examples are based on the simple CBOR value representing a bookstore (that also has a bicycle).
```json
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}
```This table shows some CBORPath queries that might be applied to this example and their intended results.
| Syntax | Intended result |
|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
| `["$", "store", "book", {"*": 1}, "author"]` | the authors of all books in the store |
| `["$", {"..": "author"}]` | all authors |
| `["$", "store", {"*": 1}]` | all things in store, which are some books
and a red bicycle |
| `["$", "store", {"..": "price"}]` | the prices of everything in the store |
| `["$", {"..": "book"}, {"#": 2}] ` | the third book |
| `["$", {"..": "book"}, {"#": -1}]` | the last book in order |
| `["$", {"..": "book"}, [{"#": 0}, {"#": 1}]]`
or
`["$", {"..": "book"}, {":": [0, 2, 1]}]` | the first two books |
| `["$", {"..": "book"}, {"?": ["@", "isbn"]}]` | all books with an ISBN number |
| `["$", {"..": "book"}, {"?": {"<": [["@", "price"], 10.0]}}]` | all books cheaper than 10 |
| `["$", {"..": {"*": 1}}]` | all map item values and array elements
contained in input value |# Library Usage
These are a few samples of code based on the examples of the previous section.
```rust
use cborpath::{CborPath, builder, Error};
use cbor_diag::parse_diag;pub fn diag_to_bytes(cbor_diag_str: &str) -> Vec {
parse_diag(cbor_diag_str).unwrap().to_bytes()
}fn main() -> Result<(), Error> {
let value = diag_to_bytes(
r#"{
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}"#,
);// the authors of all books in the store
// ["$", "store", "book", {"*": 1}, "author"]
let cbor_path = CborPath::builder()
.key("store")
.key("book")
.wildcard()
.key("author")
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]"#
),
results
);// all authors
// ["$", {"..": "author"}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("author"))
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]"#
),
results
);// all things in store, which are some books and a red bicycle
// ["$", "store", {"*": 1}]
let cbor_path = CborPath::builder().key("store").wildcard().build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
{
"color": "red",
"price": 399
}]"#
),
results
);// the prices of everything in the store
// ["$", "store", {"..": "price"}]
let cbor_path = CborPath::builder()
.key("store")
.descendant(builder::segment().key("price"))
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
399,
8.95,
12.99,
8.99,
22.99
]"#
),
results
);// the third book
// ["$", {"..": "book"}, {"#": 2}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.index(2)
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}]"#
),
results
);// the last book in order
// ["$", {"..": "book"}, {"#": -1}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.index(-1)
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}]"#
),
results
);// the first two books
// ["$", {"..": "book"}, [{"#": 0}, {"#": 1}]]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.child(builder::segment().index(0).index(1))
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}]"#
),
results
);// the first two books
// ["$", {"..": "book"}, {":": [0, 2, 1]}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.slice(0, 2, 1)
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}]"#
),
results
);// all books with an ISBN number
// ["$", {"..": "book"}, {"?": ["@", "isbn"]}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.filter(builder::rel_path().key("isbn"))
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}]"#
),
results
);// all books cheaper than 10
// ["$", {"..": "book"}, {"?": {"<": [["@", "price"], 10.0]}}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().key("book"))
.filter(builder::lt(
builder::sing_rel_path().key("price"),
builder::val(10.),
))
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}]"#
),
results
);// all map item values and array elements contained in input value
// ["$", {"..": {"*": 1}}]
let cbor_path = CborPath::builder()
.descendant(builder::segment().wildcard())
.build();
let results = cbor_path.read_from_bytes(&value)?;
assert_eq!(
diag_to_bytes(
r#"[{
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
},
[
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
{
"color": "red",
"price": 399
},
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
},
"red",
399,
"reference",
"Nigel Rees",
"Sayings of the Century",
8.95,
"fiction",
"Evelyn Waugh",
"Sword of Honour",
12.99,
"fiction",
"Herman Melville",
"Moby Dick",
"0-553-21311-3",
8.99,
"fiction",
"J. R. R. Tolkien",
"The Lord of the Rings",
"0-395-19395-8",
22.99
]"#
),
results
);Ok(())
}
```