Skip to main content

Crate jpx_engine

Crate jpx_engine 

Source
Expand description

§jpx-engine

Protocol-agnostic JMESPath query engine with 490+ functions.

This crate provides the core “brain” of jpx - everything you can do with JMESPath beyond basic compile and evaluate. It’s designed to be transport-agnostic, allowing the CLI (jpx), MCP server (jpx-mcp), or any future REST/gRPC adapters to be thin wrappers over this engine.

§Features

CategoryDescription
EvaluationSingle, batch, and string-based evaluation with validation
IntrospectionList functions, search by keyword, describe, find similar
DiscoveryCross-server tool discovery with BM25 search indexing
Query StoreNamed queries scoped to an engine instance
ConfigurationDeclarative jpx.toml config with layered discovery and merge
JSON UtilitiesFormat, diff, patch, merge, stats, paths, keys
ArrowApache Arrow conversion (optional, via arrow feature)

§Cargo Features

  • arrow - Enables Apache Arrow support for columnar data conversion. This adds the arrow module with functions to convert between Arrow RecordBatches and JSON Values. Used by the CLI for Parquet I/O.
  • let-expr - Enables let expression support (variable bindings in JMESPath expressions). Forwarded from jpx-core. Enabled by default.
  • schema - Derives JsonSchema on discovery types for JSON Schema generation. Used by the MCP server for tool schemas.

§Quick Start

use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();

// Evaluate a JMESPath expression
let result = engine.evaluate("users[*].name", &json!({
    "users": [{"name": "alice"}, {"name": "bob"}]
})).unwrap();
assert_eq!(result, json!(["alice", "bob"]));

§Evaluation

The engine supports multiple evaluation modes:

use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();

// From parsed JSON
let data = json!({"items": [1, 2, 3]});
let result = engine.evaluate("length(items)", &data).unwrap();
assert_eq!(result, json!(3));

// From JSON string
let result = engine.evaluate_str("length(@)", r#"[1, 2, 3]"#).unwrap();
assert_eq!(result, json!(3));

// Batch evaluation (multiple expressions, same input)
let exprs = vec!["a".to_string(), "b".to_string()];
let batch = engine.batch_evaluate(&exprs, &json!({"a": 1, "b": 2}));
assert_eq!(batch.results[0].result, Some(json!(1)));

// Validation without evaluation
let valid = engine.validate("users[*].name");
assert!(valid.valid);

§Function Introspection

Discover and explore the 490+ available functions:

use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

// List all categories
let categories = engine.categories();
assert!(categories.contains(&"String".to_string()));

// List functions in a category
let string_funcs = engine.functions(Some("String"));
assert!(string_funcs.iter().any(|f| f.name == "upper"));

// Search by keyword (fuzzy matching, synonyms)
let results = engine.search_functions("upper", 5);
assert!(results.iter().any(|r| r.function.name == "upper"));

// Get detailed function info
let info = engine.describe_function("upper").unwrap();
assert_eq!(info.category, "String");

// Find similar functions
let similar = engine.similar_functions("upper").unwrap();
assert!(!similar.same_category.is_empty());

§JSON Utilities

Beyond JMESPath evaluation, the engine provides JSON manipulation tools:

use jpx_engine::JpxEngine;

let engine = JpxEngine::new();

// Pretty-print JSON
let formatted = engine.format_json(r#"{"a":1}"#, 2).unwrap();
assert!(formatted.contains('\n'));

// Generate JSON Patch (RFC 6902)
let patch = engine.diff(r#"{"a": 1}"#, r#"{"a": 2}"#).unwrap();

// Apply JSON Patch
let result = engine.patch(
    r#"{"a": 1}"#,
    r#"[{"op": "replace", "path": "/a", "value": 2}]"#
).unwrap();

// Apply JSON Merge Patch (RFC 7396)
let merged = engine.merge(
    r#"{"a": 1, "b": 2}"#,
    r#"{"b": 3, "c": 4}"#
).unwrap();

// Analyze JSON structure
let stats = engine.stats(r#"[1, 2, 3]"#).unwrap();
assert_eq!(stats.root_type, "array");

§Query Store

Store and reuse named queries within a session:

use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::new();

// Define a reusable query
engine.define_query(
    "active_users".to_string(),
    "users[?active].name".to_string(),
    Some("Get names of active users".to_string())
).unwrap();

// Run it by name
let data = json!({"users": [
    {"name": "alice", "active": true},
    {"name": "bob", "active": false}
]});
let result = engine.run_query("active_users", &data).unwrap();
assert_eq!(result, json!(["alice"]));

// List all stored queries
let queries = engine.list_queries().unwrap();
assert_eq!(queries.len(), 1);

§Configuration

Load engine settings from jpx.toml files with layered discovery:

use jpx_engine::{JpxEngine, EngineConfig};

// Discover config from standard locations
// (~/.config/jpx/jpx.toml, ./jpx.toml, $JPX_CONFIG)
let config = EngineConfig::discover().unwrap();
let engine = JpxEngine::from_config(config).unwrap();

// Or use the builder for programmatic configuration
let engine = JpxEngine::builder()
    .strict(false)
    .disable_category("geo")
    .disable_function("env")
    .build()
    .unwrap();

§Tool Discovery

Register and search tools across multiple servers (for MCP integration):

use jpx_engine::{JpxEngine, DiscoverySpec};
use serde_json::json;

let engine = JpxEngine::new();

// Register a server's tools
let spec: DiscoverySpec = serde_json::from_value(json!({
    "server": {"name": "my-server", "version": "1.0.0"},
    "tools": [
        {"name": "create_user", "description": "Create a new user", "tags": ["write"]}
    ]
})).unwrap();

let result = engine.register_discovery(spec, false).unwrap();
assert!(result.ok);

// Search across registered tools
let tools = engine.query_tools("user", 10).unwrap();
assert!(!tools.is_empty());

§Strict Mode

For standard JMESPath compliance without extensions:

use jpx_engine::JpxEngine;
use serde_json::json;

let engine = JpxEngine::strict();
assert!(engine.is_strict());

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

// Extension functions are not available for evaluation
// (but introspection still works for documentation purposes)

§Architecture

   jpx-core           (parser, runtime, 490+ functions, registry)
        |
   jpx-engine         (this crate - evaluation, search, discovery, config)
        |
   +----+----+
   |         |
  jpx    jpx-mcp     (CLI and MCP transport)

§Thread Safety

The engine uses interior mutability (Arc<RwLock<...>>) for the discovery registry and query store, making it safe to share across threads. The function registry is immutable after construction.

Re-exports§

pub use config::EngineBuilder;
pub use config::EngineConfig;
pub use config::EngineSection;
pub use config::FunctionsSection;
pub use config::QueriesSection;

Modules§

ast
JMESPath Abstract Syntax Tree.
config
Engine configuration via jpx.toml.
query_library
Named Query Library parser for .jpx files.

Structs§

BatchEvaluateResult
Result of batch evaluation.
BatchExpressionResult
Result for a single expression in batch evaluation.
Bm25Index
BM25 index structure - fully JSON serializable
Bm25SearchResult
Search result
CategoryInfo
Category information
CategorySummary
Summary information about a tool category.
DiscoveryRegistry
Discovery registry - holds registered specs and search index
DiscoverySpec
Discovery spec - the schema MCP servers use to register their tools
DocInfo
Document metadata
EvalRequest
Request to evaluate a JMESPath expression.
EvalResponse
Response from evaluating a JMESPath expression.
ExampleSpec
Example specification
ExplainResult
Step-by-step breakdown of a JMESPath expression.
ExplainStep
A single step in the expression breakdown.
Expression
A compiled JMESPath expression.
FieldAnalysis
Analysis of a field across an array of objects.
FunctionDetail
Detailed information about a JMESPath function.
FunctionInfo
Metadata about a function.
FunctionRegistry
Registry for managing function availability at runtime.
IndexOptions
Index configuration options
IndexStats
Statistics about the discovery search index.
JpxEngine
The JMESPath query engine.
ParamSpec
Parameter specification
PathInfo
Information about a path in a JSON structure.
QueryStore
In-memory storage for named queries.
RegistrationResult
Result of registering a discovery spec.
ReturnSpec
Return type specification
Runtime
Compiles JMESPath expressions and manages registered functions.
SearchResult
Result from searching for functions.
ServerInfo
Server metadata
ServerSummary
Summary information about a registered server.
SimilarFunctionsResult
Result from finding functions similar to a given function.
StatsResult
Statistics about JSON data structure.
StoredQuery
A named JMESPath query with optional description.
TermInfo
Term information in the inverted index
ToolQueryResult
Result from querying tools across registered servers.
ToolSpec
Tool specification
ValidationResult
Result of validating a JMESPath expression.

Enums§

Category
Function category matching compile-time features.
EngineError
Errors that can occur during engine operations.
EvaluationErrorKind
Classifies the specific failure mode of an evaluation error.

Functions§

compile
Compiles a JMESPath expression using the default Runtime.
has_let_nodes
Returns true if the AST contains any Let or VariableRef nodes.
parse
Parses a JMESPath expression into an AST.

Type Aliases§

Result
A specialized Result type for engine operations.