Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing static compile method; use runtime instances instead #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions jmespath-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::process::exit;
use std::rc::Rc;

use clap::{App, Arg};
use jmespath::Rcvar;
use jmespath::{compile, Variable};
use jmespath::{Rcvar};
use jmespath::{Variable};

macro_rules! die(
($msg:expr) => (
Expand Down Expand Up @@ -66,10 +66,12 @@ fn main() {
.value_of("expr-file")
.map(|f| read_file("expression", f));

let runtime = jmespath::create_default_runtime();

let expr = if let Some(ref e) = file_expression {
compile(e)
runtime.compile(e)
} else {
compile(matches.value_of("expression").unwrap())
runtime.compile(matches.value_of("expression").unwrap())
}
.map_err(|e| die!(e.to_string()))
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion jmespath/benches/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
//extern crate bencher;

use bencher::*;
use jmespath::{compile, parse, Rcvar, Variable};
use jmespath::{parse, Rcvar, Variable};

include!(concat!(env!("OUT_DIR"), "/benches.rs"));
47 changes: 16 additions & 31 deletions jmespath/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@
//! # 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`.
//! a custom `Runtime`.
//!
//! ```
//! use jmespath::{Runtime, Context, Rcvar};
Expand Down Expand Up @@ -109,8 +105,6 @@ use serde_json::Value;
use std::convert::TryInto;
use std::fmt;

use lazy_static::*;

use crate::ast::Ast;
use crate::interpreter::{interpret, SearchResult};

Expand All @@ -121,12 +115,10 @@ mod parser;
mod runtime;
mod variable;

lazy_static! {
pub static ref DEFAULT_RUNTIME: Runtime = {
let mut runtime = Runtime::new();
runtime.register_builtin_functions();
runtime
};
pub fn create_default_runtime() -> Runtime {
let mut runtime = Runtime::new();
runtime.register_builtin_functions();
runtime
}

/// `Rc` reference counted JMESPath `Variable`.
Expand All @@ -136,18 +128,6 @@ pub type Rcvar = std::rc::Rc<Variable>;
#[cfg(feature = "sync")]
pub type Rcvar = std::sync::Arc<Variable>;

/// Compiles a JMESPath expression using the default Runtime.
///
/// The default Runtime is created lazily the first time it is dereferenced
/// by using the `lazy_static` macro.
///
/// The provided expression is expected to adhere to the JMESPath
/// grammar: <https://jmespath.org/specification.html>
#[inline]
pub fn compile(expression: &str) -> Result<Expression<'static>, JmespathError> {
DEFAULT_RUNTIME.compile(expression)
}

/// Converts a value into a reference-counted JMESPath Variable.
///
#[cfg_attr(
Expand Down Expand Up @@ -466,27 +446,31 @@ mod test {

#[test]
fn formats_expression_as_string_or_debug() {
let expr = compile("foo | baz").unwrap();
let runtime = create_default_runtime();
let expr = runtime.compile("foo | baz").unwrap();
assert_eq!("foo | baz/foo | baz", format!("{}/{:?}", expr, expr));
}

#[test]
fn implements_partial_eq() {
let a = compile("@").unwrap();
let b = compile("@").unwrap();
let runtime = create_default_runtime();
let a = runtime.compile("@").unwrap();
let b = runtime.compile("@").unwrap();
assert!(a == b);
}

#[test]
fn can_evaluate_jmespath_expression() {
let expr = compile("foo.bar").unwrap();
let runtime = create_default_runtime();
let expr = runtime.compile("foo.bar").unwrap();
let var = Variable::from_json("{\"foo\":{\"bar\":true}}").unwrap();
assert_eq!(Rcvar::new(Variable::Bool(true)), expr.search(var).unwrap());
}

#[test]
fn can_get_expression_ast() {
let expr = compile("foo").unwrap();
let runtime = create_default_runtime();
let expr = runtime.compile("foo").unwrap();
assert_eq!(
&Ast::Field {
offset: 0,
Expand All @@ -505,7 +489,8 @@ mod test {

#[test]
fn expression_clone() {
let expr = compile("foo").unwrap();
let runtime = create_default_runtime();
let expr = runtime.compile("foo").unwrap();
let _ = expr.clone();
}
}
24 changes: 13 additions & 11 deletions jmespath/tests/compliance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use serde_json::Value;
use std::fmt;

use jmespath::{compile, Expression, Rcvar, RuntimeError, Variable};
use jmespath::{Expression, Rcvar, RuntimeError, Variable, Runtime};

/// Avaliable benchmark types.
pub enum BenchType {
Expand Down Expand Up @@ -101,10 +101,16 @@ pub enum Assertion {
impl Assertion {
/// Runs the assertion of a test case
pub fn assert(&self, suite: &str, case: &TestCase, given: Rcvar) -> Result<(), String> {
let runtime = jmespath::create_default_runtime();

match self {
&Assertion::Bench(_) => Ok(()),
&Assertion::ValidResult(ref expected_result) => {
let expr = self.try_parse(suite, case)?;
let expr = match runtime.compile(&case.expression) {
Err(e) => Err(self.err_message(suite, case, format!("{}", e))),
Ok(expr) => Ok(expr),
}?;

match expr.search(given) {
Err(e) => Err(self.err_message(suite, case, format!("{}", e))),
Ok(r) => {
Expand All @@ -122,7 +128,11 @@ impl Assertion {
}
&Assertion::Error(ref error_type) => {
use jmespath::ErrorReason::*;
let result = self.try_parse(suite, case);
let result = match runtime.compile(&case.expression) {
Err(e) => Err(self.err_message(suite, case, format!("{}", e))),
Ok(expr) => Ok(expr),
};

match error_type {
&ErrorType::InvalidArity => match result?.search(given).map_err(|e| e.reason) {
Err(Runtime(RuntimeError::NotEnoughArguments { .. })) => Ok(()),
Expand Down Expand Up @@ -159,14 +169,6 @@ impl Assertion {
}
}

/// Attempts to parse an expression for a case, returning the expression or an error string.
fn try_parse(&self, suite: &str, case: &TestCase) -> Result<Expression<'_>, String> {
match compile(&case.expression) {
Err(e) => Err(self.err_message(suite, case, format!("{}", e))),
Ok(expr) => Ok(expr),
}
}

/// Formats an error message for a test case failure.
fn err_message(&self, suite: &str, case: &TestCase, message: String) -> String {
format!(
Expand Down