Skip to content

Commit

Permalink
feat: Add regex feature flag
Browse files Browse the repository at this point in the history
This hides the regex functions (`match` and `search`) behind a feature flag `regex`, which is enabled by default. This allows consumers to completely eliminate regex as a dependency if they choose.

Also added some docs on feature flags.
  • Loading branch information
LucasPickering committed Jul 31, 2024
1 parent c0dd50a commit 608512e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 7 deletions.
2 changes: 2 additions & 0 deletions serde_json_path/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased

- **fixed**: edge case where `.` in regexes for `match` and `search` functions was matching `\r\n` properly ([#92])
- **breaking**: added `regex` feature flag that gates regex functions `match` and `search`
- Feature is enabled by default, but if you have `default-features = false` you'll need to explicitly add it to retain access to these functions

[#92]: https://github.com/hiltontj/serde_json_path/pull/92

Expand Down
5 changes: 3 additions & 2 deletions serde_json_path/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ readme = "README.md"
keywords = ["json", "jsonpath", "json_path", "serde", "serde_json"]

[features]
default = ["functions"]
default = ["functions", "regex"]
regex = ["dep:regex"]
trace = ["dep:tracing", "serde_json_path_core/trace"]
functions = ["serde_json_path_core/functions"]

[dependencies]
inventory = { version = "0.3.4" }
nom = "7.1.3"
once_cell = { version = "1.17.1" }
regex = "1.7.1"
regex = { version="1.7.1", optional = true }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_json_path_core = { path = "../serde_json_path_core", version = "0.1.6" }
Expand Down
8 changes: 8 additions & 0 deletions serde_json_path/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,14 @@
//! # Ok(())
//! # }
//! ```
//!
//! ## Feature Flags
//!
//! The following feature flags are supported:
//!
//! - `tracing` - Enable internal tracing via [tracing]

Check failure on line 319 in serde_json_path/src/lib.rs

View workflow job for this annotation

GitHub Actions / Docs

unresolved link to `tracing`
//! - `functions` - Enable user-defined functions
//! - `regex` - Enable the `match` and `search` functions
#![warn(
clippy::all,
Expand Down
14 changes: 9 additions & 5 deletions serde_json_path/src/parser/selector/function/registry.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;

use once_cell::sync::Lazy;
use regex::Regex;
use serde_json::Value;
use serde_json_path_core::spec::functions::{Function, LogicalType, NodesType, ValueType};

Expand All @@ -20,8 +19,11 @@ pub(crate) static REGISTRY: Lazy<HashMap<&'static str, &'static Function>> = Laz
let mut m = HashMap::new();
m.insert("length", &LENGTH_FUNC);
m.insert("count", &COUNT_FUNC);
m.insert("match", &MATCH_FUNC);
m.insert("search", &SEARCH_FUNC);
#[cfg(feature = "regex")]
{
m.insert("match", &MATCH_FUNC);
m.insert("search", &SEARCH_FUNC);
}
m.insert("value", &VALUE_FUNC);
m
});
Expand Down Expand Up @@ -50,11 +52,12 @@ fn count(nodes: NodesType) -> ValueType {
nodes.len().into()
}

#[cfg(feature = "regex")]
#[serde_json_path_macros::register(name = "match", target = MATCH_FUNC)]
fn match_func(value: ValueType, rgx: ValueType) -> LogicalType {
match (value.as_value(), rgx.as_value()) {
(Some(Value::String(s)), Some(Value::String(r))) => {
Regex::new(format!("(?R)^({r})$").as_str())
regex::Regex::new(format!("(?R)^({r})$").as_str())
.map(|r| r.is_match(s))
.map(Into::into)
.unwrap_or_default()
Expand All @@ -63,11 +66,12 @@ fn match_func(value: ValueType, rgx: ValueType) -> LogicalType {
}
}

#[cfg(feature = "regex")]
#[serde_json_path_macros::register(target = SEARCH_FUNC)]
fn search(value: ValueType, rgx: ValueType) -> LogicalType {
match (value.as_value(), rgx.as_value()) {
(Some(Value::String(s)), Some(Value::String(r))) => {
Regex::new(format!("(?R)({r})").as_str())
regex::Regex::new(format!("(?R)({r})").as_str())
.map(|r| r.is_match(s))
.map(Into::into)
.unwrap_or_default()
Expand Down

0 comments on commit 608512e

Please sign in to comment.