JSON Pointer and JSONPath query utilities for MoonBit
Dependencies
moon check
moon testmoon run cmd/main -- query '$.users[*].name' data.json
moon run cmd/main -- query --pointers '$..name' data.json
moon run cmd/main -- query --matches --pretty '$.users[?(@.age > 20)]' data.json
moon run cmd/main -- get '/users/0/name' data.json
moon run cmd/main -- set '/users/0/active' true data.json
moon run cmd/main -- remove '/users/0/secret' data.json
moon run cmd/main -- patch patch.json data.jsonmoon run cmd/main///|
test {
let doc : Json = {
"users": [
{ "name": "Ada", "age": 36, "active": true },
{ "name": "Grace", "age": 85, "active": false },
],
}
let path = @moonjsonpath.Path::compile("$.users[?(@.age > 40)].name").unwrap()
let matches = path.query(doc)
inspect(matches[0].pointer.to_string(), content="/users/1/name")
@json.json_inspect(matches.map(item => item.value), content=["Grace"])
}///|
test {
let doc : Json = { "meta": { "count": 2 }, "tags": ["old"] }
let pointer = @moonjsonpath.Pointer::parse("/meta/count").unwrap()
@json.json_inspect(pointer.get(doc).unwrap(), content=2)
let updated = pointer.set(doc, 3).unwrap()
@json.json_inspect(updated, content={
"meta": { "count": 3 },
"tags": ["old"],
})
}| Feature | Example |
|---|---|
| Root | $ |
| Dot member | $.users |
| Quoted member | $['display name'] |
| Array index | $.users[0] |
| Negative index | $.users[-1] |
| Wildcard | $.users[*], $.meta.* |
| Recursive member | $..name |
| Slice | $.items[1:4], $.items[::-1] |
| Union | $.items[0,2], $.meta['owner','count'] |
| Filter | $.users[?(@.active == true)] |
$.users[?(@.age >= 18)]
$.users[?(@.active == true && @.role == "admin")]
$.users[?(@.name starts_with "A" || @.name contains "ace")]
$.files[?(@.name ends_with ".mbt")]
$.items[?(@.tags.length >= 2)]
$.items[?(!(@.hidden == true))]///|
test {
let doc : Json = {
"users": [{ "name": "Ada", "active": false }],
"secret": true,
}
let changed = @moonjsonpath.apply_patch(doc, [
@moonjsonpath.PatchOp::replace("/users/0/active", true),
@moonjsonpath.PatchOp::remove("/secret"),
]).unwrap()
@json.json_inspect(changed, content={
"users": [{ "name": "Ada", "active": true }],
})
}Usage:
moonjsonpath query [--values|--pointers|--matches] [--pretty] <jsonpath> <file>
moonjsonpath get [--pretty] <pointer> <file>
moonjsonpath set [--pretty] <pointer> <json-value> <file>
moonjsonpath remove [--pretty] <pointer> <file>
moonjsonpath patch [--pretty] <patch-file> <file>
Legacy:
moonjsonpath [--values|--pointers|--matches] [--pretty] <jsonpath> <file>{
"users": [
{ "name": "Ada", "active": false },
{ "name": "Grace", "active": true }
]
}moon run cmd/main -- query '$.users[*].name' users.json
# ["Ada","Grace"]
moon run cmd/main -- query --pointers '$.users[*].name' users.json
# ["/users/0/name","/users/1/name"]
moon run cmd/main -- get '/users/0/name' users.json
# "Ada"
moon run cmd/main -- set '/users/0/active' true users.json
# {"users":[{"name":"Ada","active":true},{"name":"Grace","active":true}]}moonjsonpath/
├── moonjsonpath.mbt # Core Pointer and JSONPath implementation
├── patch.mbt # Pointer Patch operations
├── transform.mbt # Text-based JSON transform helpers
├── cli_command.mbt # CLI parser and command execution
├── query_helpers.mbt # Convenience query APIs
├── explain.mbt # JSONPath explain/introspection helpers
├── pointer_uri.mbt # JSON Pointer URI fragment support
├── cookbook.mbt # Runnable cookbook examples
├── *_test.mbt # Unit, catalog, conformance, and CLI tests
├── cmd/main/ # CLI executable entry point
├── docs/ # Contest proposal and project notes
├── moon.mod # MoonBit module metadata
└── moon.pkg # Package importsmoon fmt
moon info
moon check
moon testpub(all) struct CliCommand {
kind : CliCommandKind
path_text : String
pointer_text : String
value_text : String
patch_file_path : String
file_path : String
output : OutputMode
indent : Int
} derive(Eq, Debug)pub(all) struct CliConfig {
path_text : String
file_path : String
options : QueryOptions
show_help : Bool
} derive(Eq, Debug)pub(all) struct CookbookEntry {
id : String
title : String
json_text : String
path_text : String
output_mode : OutputMode
expected : String
note : String
} derive(Eq, Debug)pub(all) enum FilterExpr {
Exists(Array[String])
Compare(Array[String], CompareOp, Literal)
StringMatch(Array[String], StringOp, String)
LengthCompare(Array[String], CompareOp, Literal)
And(FilterExpr, FilterExpr)
Or(FilterExpr, FilterExpr)
Not(FilterExpr)
} derive(Eq, Debug)pub(all) enum PathSegment {
Member(String)
Element(Int)
Wildcard
RecursiveMember(String)
Slice(Int?, Int?, Int?)
Filter(FilterExpr)
Union(Array[PathSegment])
} derive(Eq, Debug)pub(all) struct PointerError {
kind : PointerErrorKind
path : String
message : String
} derive(Eq, Debug)fn execute_cli_text(command : CliCommand, json_text : String, patch_text : String) -> Result[String, String]fn patch_json_text(patch_text : String, json_text : String, indent? : Int) -> Result[String, String]fn pointer_get_json_text(pointer_text : String, json_text : String, indent? : Int) -> Result[String, String]fn pointer_remove_json_text(pointer_text : String, json_text : String, indent? : Int) -> Result[String, String]fn pointer_set_json_text(pointer_text : String, value_text : String, json_text : String, indent? : Int) -> Result[String, String]fn query_exists_json_text(path_text : String, json_text : String) -> Result[Bool, String]fn query_first_json_text(path_text : String, json_text : String, indent? : Int) -> Result[String, String]fn query_json_file(path_text : String, file_path : String) -> Result[String, String]fn query_json_file_with_options(path_text : String, file_path : String, options : QueryOptions) -> Result[String, String]fn query_json_text(path_text : String, json_text : String) -> Result[String, String]fn query_json_text_with_options(path_text : String, json_text : String, options : QueryOptions) -> Result[String, String]fn query_pointers_json_text(path_text : String, json_text : String, indent? : Int) -> Result[String, String]fn query_values_json_text(path_text : String, json_text : String, indent? : Int) -> Result[String, String]JSON Pointer and JSONPath query utilities for MoonBit
Dependencies