Skip to main content

JpxEngine

Struct JpxEngine 

Source
pub struct JpxEngine { /* private fields */ }
Expand description

The JMESPath query engine.

JpxEngine is the main entry point for all jpx functionality. It combines:

  • JMESPath runtime with 400+ extension functions
  • Function registry for introspection and search
  • Discovery registry for cross-server tool indexing
  • Query store for named query management

§Construction

use jpx_engine::JpxEngine;

// Full engine with all extensions
let engine = JpxEngine::new();

// Strict mode (standard JMESPath only)
let strict_engine = JpxEngine::strict();

// Or using Default
let default_engine = JpxEngine::default();

§Thread Safety

The engine is designed to be shared across threads. The discovery registry and query store use Arc<RwLock<...>> for interior mutability, while the function registry is immutable after construction.

use jpx_engine::JpxEngine;
use std::sync::Arc;

let engine = Arc::new(JpxEngine::new());

// Clone the Arc to share across threads
let engine_clone = Arc::clone(&engine);
std::thread::spawn(move || {
    let result = engine_clone.evaluate("length(@)", &serde_json::json!([1, 2, 3]));
});

Implementations§

Source§

impl JpxEngine

Source

pub fn new() -> Self

Creates a new engine with all extension functions enabled.

This is the standard way to create an engine with full functionality, including all 400+ extension functions.

§Example
use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();

// Standard JMESPath works
let result = engine.evaluate("name", &json!({"name": "alice"})).unwrap();
assert_eq!(result, json!("alice"));

// Extension functions also work
let result = engine.evaluate("upper(name)", &json!({"name": "alice"})).unwrap();
assert_eq!(result, json!("ALICE"));
Source

pub fn with_options(strict: bool) -> Self

Creates a new engine with configurable strict mode.

§Arguments
  • strict - If true, only standard JMESPath functions are available for evaluation. Introspection features still show all functions.
§Example
use jpx_engine::JpxEngine;

// Create engine with extensions
let full_engine = JpxEngine::with_options(false);

// Create strict engine (standard JMESPath only)
let strict_engine = JpxEngine::with_options(true);
assert!(strict_engine.is_strict());
Source

pub fn strict() -> Self

Creates a new engine in strict mode (standard JMESPath only).

Equivalent to JpxEngine::with_options(true).

§Example
use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::strict();

// Standard functions work
let result = engine.evaluate("length(@)", &json!([1, 2, 3])).unwrap();
assert_eq!(result, json!(3));
Source

pub fn is_strict(&self) -> bool

Returns true if the engine is in strict mode.

In strict mode, only standard JMESPath functions are available for evaluation. Extension functions will cause evaluation errors.

Source

pub fn runtime(&self) -> &Runtime

Returns a reference to the underlying JMESPath runtime.

This provides access to the low-level runtime for advanced use cases.

Source

pub fn registry(&self) -> &FunctionRegistry

Returns a reference to the function registry.

The registry contains metadata about all available functions and can be used for custom introspection beyond what the engine methods provide.

Source

pub fn discovery(&self) -> &Arc<RwLock<DiscoveryRegistry>>

Returns a reference to the discovery registry.

The discovery registry manages cross-server tool indexing and search. Access is through Arc<RwLock<...>> for thread-safe mutation.

Source

pub fn queries(&self) -> &Arc<RwLock<QueryStore>>

Returns a reference to the query store.

The query store manages named queries for the session. Access is through Arc<RwLock<...>> for thread-safe mutation.

Source

pub fn evaluate(&self, expression: &str, input: &Value) -> Result<Value>

Evaluates a JMESPath expression against JSON input.

This is the primary method for running JMESPath queries. The expression is compiled and executed against the provided JSON value.

§Arguments
  • expression - A JMESPath expression string
  • input - JSON data to query
§Errors

Returns EngineError::InvalidExpression if the expression has syntax errors, or EngineError::EvaluationFailed if evaluation fails (e.g., calling an undefined function in strict mode).

§Example
use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();

// Simple field access
let result = engine.evaluate("name", &json!({"name": "alice"})).unwrap();
assert_eq!(result, json!("alice"));

// Array projection with function
let result = engine.evaluate("users[*].name | sort(@)", &json!({
    "users": [{"name": "charlie"}, {"name": "alice"}, {"name": "bob"}]
})).unwrap();
assert_eq!(result, json!(["alice", "bob", "charlie"]));
Source

pub fn evaluate_str(&self, expression: &str, input: &str) -> Result<Value>

Evaluates a JMESPath expression against a JSON string.

Convenience method that parses the JSON string before evaluation.

§Errors

Returns EngineError::InvalidJson if the input is not valid JSON, or evaluation errors as with evaluate.

§Example
use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();
let result = engine.evaluate_str("length(@)", r#"[1, 2, 3, 4, 5]"#).unwrap();
assert_eq!(result, json!(5));
Source

pub fn batch_evaluate( &self, expressions: &[String], input: &Value, ) -> BatchEvaluateResult

Evaluates multiple expressions against the same input.

Useful for extracting multiple values from a document in one call. Each expression is evaluated independently; failures don’t affect other expressions.

§Example
use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();
let input = json!({"name": "alice", "age": 30, "active": true});

let exprs = vec![
    "name".to_string(),
    "age".to_string(),
    "missing".to_string(),  // Returns null, not an error
];

let results = engine.batch_evaluate(&exprs, &input);
assert_eq!(results.results[0].result, Some(json!("alice")));
assert_eq!(results.results[1].result, Some(json!(30)));
assert_eq!(results.results[2].result, Some(json!(null)));
Source

pub fn validate(&self, expression: &str) -> ValidationResult

Validates a JMESPath expression without evaluating it.

Checks if an expression has valid syntax without needing input data. Useful for validating user-provided expressions before storing them.

§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

// Valid expression
let result = engine.validate("users[*].name | sort(@)");
assert!(result.valid);
assert!(result.error.is_none());

// Invalid expression (unclosed bracket)
let result = engine.validate("users[*.name");
assert!(!result.valid);
assert!(result.error.is_some());
Source

pub fn categories(&self) -> Vec<String>

Lists all available function categories.

Returns category names like “String”, “Math”, “Datetime”, etc.

§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();
let categories = engine.categories();

assert!(categories.contains(&"String".to_string()));
assert!(categories.contains(&"Math".to_string()));
assert!(categories.contains(&"Array".to_string()));
Source

pub fn functions(&self, category: Option<&str>) -> Vec<FunctionDetail>

Lists functions, optionally filtered by category.

§Arguments
  • category - Optional category name to filter by (case-insensitive)
§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

// All functions
let all = engine.functions(None);
assert!(all.len() > 100);

// Just string functions
let string_funcs = engine.functions(Some("String"));
assert!(string_funcs.iter().all(|f| f.category == "String"));
Source

pub fn describe_function(&self, name: &str) -> Option<FunctionDetail>

Gets detailed information about a function by name or alias.

§Arguments
  • name - Function name or alias (e.g., “upper”, “md5”, “len”)
§Returns

Some(FunctionDetail) if found, None if no matching function exists.

§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

let info = engine.describe_function("upper").unwrap();
assert_eq!(info.category, "String");
println!("Signature: {}", info.signature);
println!("Example: {}", info.example);

// Also works with aliases
let info = engine.describe_function("len");  // alias for "length"
Source

pub fn search_functions(&self, query: &str, limit: usize) -> Vec<SearchResult>

Searches for functions matching a query string.

Uses fuzzy matching, synonyms, and searches across names, descriptions, categories, and signatures. Results are ranked by relevance.

§Arguments
  • query - Search term (e.g., “hash”, “string manipulation”, “date”)
  • limit - Maximum number of results to return
§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

// Search by concept
let results = engine.search_functions("hash", 10);
assert!(results.iter().any(|r| r.function.name == "md5"));
assert!(results.iter().any(|r| r.function.name == "sha256"));

// Results are ranked by relevance
for result in &results {
    println!("{}: {} (score: {})",
        result.function.name,
        result.match_type,
        result.score
    );
}
Source

pub fn similar_functions(&self, name: &str) -> Option<SimilarFunctionsResult>

Finds functions similar to a given function.

Returns functions grouped by relationship type:

  • Same category (e.g., other string functions if input is “upper”)
  • Similar signature (same parameter/return types)
  • Related concepts (overlapping description keywords)
§Arguments
  • name - Name of the function to find similar functions for
§Returns

Some(SimilarFunctionsResult) if the function exists, None otherwise.

§Example
use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

let similar = engine.similar_functions("upper").unwrap();

// Other string functions
println!("Same category:");
for f in &similar.same_category {
    println!("  - {}", f.name);
}
Source

pub fn format_json(&self, input: &str, indent: usize) -> Result<String>

Format JSON with indentation.

Source

pub fn diff(&self, source: &str, target: &str) -> Result<Value>

Generate a JSON Patch (RFC 6902) from source to target.

Source

pub fn patch(&self, input: &str, patch: &str) -> Result<Value>

Apply a JSON Patch (RFC 6902) to a document.

Source

pub fn merge(&self, input: &str, patch: &str) -> Result<Value>

Apply a JSON Merge Patch (RFC 7396) to a document.

Source

pub fn keys(&self, input: &str, recursive: bool) -> Result<Vec<String>>

Extract keys from a JSON object.

Source

pub fn paths( &self, input: &str, include_types: bool, include_values: bool, ) -> Result<Vec<PathInfo>>

Extract all paths from JSON data.

Source

pub fn stats(&self, input: &str) -> Result<StatsResult>

Analyze JSON data and return statistics.

Source

pub fn define_query( &self, name: String, expression: String, description: Option<String>, ) -> Result<Option<StoredQuery>>

Define (store) a named query.

Source

pub fn get_query(&self, name: &str) -> Result<Option<StoredQuery>>

Get a stored query by name.

Source

pub fn delete_query(&self, name: &str) -> Result<Option<StoredQuery>>

Delete a stored query.

Source

pub fn list_queries(&self) -> Result<Vec<StoredQuery>>

List all stored queries.

Source

pub fn run_query(&self, name: &str, input: &Value) -> Result<Value>

Run a stored query.

Source

pub fn register_discovery( &self, spec: DiscoverySpec, replace: bool, ) -> Result<RegistrationResult>

Register a discovery spec.

Source

pub fn unregister_discovery(&self, server_name: &str) -> Result<bool>

Unregister a server from discovery.

Source

pub fn query_tools( &self, query: &str, top_k: usize, ) -> Result<Vec<ToolQueryResult>>

Query tools across registered servers.

Source

pub fn similar_tools( &self, tool_id: &str, top_k: usize, ) -> Result<Vec<ToolQueryResult>>

Find tools similar to a given tool.

Source

pub fn list_discovery_servers(&self) -> Result<Vec<ServerSummary>>

List all registered discovery servers.

Source

pub fn list_discovery_categories( &self, ) -> Result<HashMap<String, CategorySummary>>

List discovery categories.

Source

pub fn discovery_index_stats(&self) -> Result<Option<IndexStats>>

Get discovery index stats.

Source

pub fn get_discovery_schema(&self) -> Value

Get the discovery schema.

Trait Implementations§

Source§

impl Default for JpxEngine

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V