5 releases (3 breaking)
0.3.0 | Feb 24, 2022 |
---|---|
0.2.0 | Aug 26, 2017 |
0.1.1 | Jan 8, 2017 |
0.1.0 | Dec 16, 2016 |
0.0.1 | Jan 31, 2016 |
#607 in Encoding
30,567 downloads per month
Used in 15 crates
(8 directly)
165KB
4K
SLoC
Rust implementation of JMESPath, a query language for JSON.
Compiling JMESPath expressions
Use the jmespath::compile
function to compile JMESPath expressions
into reusable Expression
structs. The Expression
struct can be
used multiple times on different values without having to recompile
the expression.
use jmespath;
let expr = jmespath::compile("foo.bar | baz").unwrap();
// Parse some JSON data into a JMESPath variable
let json_str = "{\"foo\":{\"bar\":{\"baz\":true}}}";
let data = jmespath::Variable::from_json(json_str).unwrap();
// Search the data with the compiled expression
let result = expr.search(data).unwrap();
assert_eq!(true, result.as_boolean().unwrap());
You can get the original expression as a string and the parsed expression
AST from the Expression
struct:
use jmespath;
use jmespath::ast::Ast;
let expr = jmespath::compile("foo").unwrap();
assert_eq!("foo", expr.as_str());
assert_eq!(&Ast::Field {name: "foo".to_string(), offset: 0}, expr.as_ast());
JMESPath variables
In order to evaluate expressions against a known data type, the
jmespath::Variable
enum is used as both the input and output type.
More specifically, Rcvar
(or jmespath::Rcvar
) is used to allow
shared, reference counted data to be used by the JMESPath interpreter at
runtime.
By default, Rcvar
is an std::rc::Rc<Variable>
. However, by specifying
the sync
feature, you can utilize an std::sync::Arc<Variable>
to
share Expression
structs across threads.
Any type that implements jmespath::ToJmespath
can be used in a JMESPath
Expression. Various types have default ToJmespath
implementations,
including serde::ser::Serialize
. Because jmespath::Variable
implements
serde::ser::Serialize
, many existing types can be searched without needing
an explicit coercion, and any type that needs coercion can be implemented
using serde's macros or code generation capabilities. This includes a
number of common types, including serde's serde_json::Value
enum.
The return value of searching data with JMESPath is also an Rcvar
.
Variable
has a number of helper methods that make it a data type that
can be used directly, or you can convert Variable
to any serde value
implementing serde::de::Deserialize
.
Custom Functions
You can register custom functions with a JMESPath expression by using
a custom Runtime
. When you call jmespath::compile
, you are using a
shared Runtime
instance that is created lazily using lazy_static
.
This shared Runtime
utilizes all of the builtin JMESPath functions
by default. However, custom functions may be utilized by creating a custom
Runtime
and compiling expressions directly from the Runtime
.
use jmespath::{Runtime, Context, Rcvar};
use jmespath::functions::{CustomFunction, Signature, ArgumentType};
// Create a new Runtime and register the builtin JMESPath functions.
let mut runtime = Runtime::new();
runtime.register_builtin_functions();
// Create an identity string function that returns string values as-is.
runtime.register_function("str_identity", Box::new(CustomFunction::new(
Signature::new(vec![ArgumentType::String], None),
Box::new(|args: &[Rcvar], _: &mut Context| Ok(args[0].clone()))
)));
// You can also use normal closures as functions.
runtime.register_function("identity",
Box::new(|args: &[Rcvar], _: &mut Context| Ok(args[0].clone())));
let expr = runtime.compile("str_identity('foo')").unwrap();
assert_eq!("foo", expr.search(()).unwrap().as_string().unwrap());
let expr = runtime.compile("identity('bar')").unwrap();
assert_eq!("bar", expr.search(()).unwrap().as_string().unwrap());
Dependencies
~0.5–1MB
~20K SLoC