A small MoonBit JSONPath parser and evaluator for RFC 9535 core query patterns.
ppyj663/moon-jsonpathmoon add ppyj663/moon-jsonpathimport {
"ppyj663/moon-jsonpath" @jsonpath,
}let json = @json.parse(
#|{
#| "store": {
#| "book": [
#| { "title": "Sayings of the Century", "price": 8.95 },
#| { "title": "Sword of Honour", "price": 12.99 }
#| ]
#| }
#|}
)
match @jsonpath.query(json, "$.store.book[0].title") {
Ok(values) => println(values[0].stringify())
Err(message) => println("query failed: \{message}")
}moon run cmd/mainquery: $.store.book[0].title
matches: 1
"Sayings of the Century"| Syntax | Meaning | Example |
|---|---|---|
| $ | Root node | $ |
| .<name> | Object child selector | $.store.bicycle |
| ['<name>'] or ["<name>"] | Bracket child selector (supports string escapes) | $['store']['book'] |
| .. <name> without the space | Recursive descendant selector | $..price |
| .* / [*] | Object or array wildcard | $.store.book[*] |
| [<number>] | Array index (supports negative indices) | $.store.book[-1] |
| [<start>:<end>:<step>] | Array slicing (supports positive and negative steps) | $.store.book[1:3] |
| [<sel1>, <sel2>] | Union selector | $.store.book[0, 2] |
| [?(<expr>)] | Filter selector (supports comparisons, logical AND/OR/NOT) | $.store.book[?(@.price < 10)] |
pub fn parse(input : String) -> Result[JSONPath, String]
pub fn evaluate(json : Json, path : JSONPath) -> Array[Json]
pub fn query(json : Json, path_str : String) -> Result[Array[Json], String]moon update
moon fmt --check
moon check --deny-warn
moon test
moon run cmd/mainpub enum FilterExpr {
Exists(PathExpr)
Eq(FilterVal, FilterVal)
Ne(FilterVal, FilterVal)
Lt(FilterVal, FilterVal)
Le(FilterVal, FilterVal)
Gt(FilterVal, FilterVal)
Ge(FilterVal, FilterVal)
And(FilterExpr, FilterExpr)
Or(FilterExpr, FilterExpr)
Not(FilterExpr)
Value(FilterVal)
} derive(Eq, Debug)pub enum Selector {
Name(String)
Index(Int)
Wildcard
Slice(Int?, Int?, Int?)
Filter(FilterExpr)
} derive(Eq, Debug)A small MoonBit JSONPath parser and evaluator for RFC 9535 core query patterns.