serde_json_path/parser/selector/function/
registry.rs1use std::{collections::HashMap, sync::LazyLock};
2
3use serde_json::Value;
4use serde_json_path_core::spec::functions::{Function, LogicalType, NodesType, ValueType};
5
6pub(crate) static REGISTRY: LazyLock<HashMap<&'static str, &'static Function>> =
18 LazyLock::new(|| {
19 let mut m = HashMap::new();
20 m.insert("length", &LENGTH_FUNC);
21 m.insert("count", &COUNT_FUNC);
22 #[cfg(feature = "regex")]
23 {
24 m.insert("match", &MATCH_FUNC);
25 m.insert("search", &SEARCH_FUNC);
26 }
27 m.insert("value", &VALUE_FUNC);
28 m
29 });
30
31fn value_length(value: &Value) -> Option<usize> {
32 match value {
33 Value::String(s) => Some(s.chars().count()),
34 Value::Array(a) => Some(a.len()),
35 Value::Object(o) => Some(o.len()),
36 _ => None,
37 }
38}
39
40#[serde_json_path_macros::register(target = LENGTH_FUNC)]
41fn length(value: ValueType) -> ValueType {
42 match value {
43 ValueType::Value(v) => value_length(&v),
44 ValueType::Node(v) => value_length(v),
45 ValueType::Nothing => None,
46 }
47 .map_or(ValueType::Nothing, |l| ValueType::Value(l.into()))
48}
49
50#[serde_json_path_macros::register(target = COUNT_FUNC)]
51fn count(nodes: NodesType) -> ValueType {
52 nodes.len().into()
53}
54
55#[cfg(feature = "regex")]
56#[serde_json_path_macros::register(name = "match", target = MATCH_FUNC)]
57fn match_func(value: ValueType, rgx: ValueType) -> LogicalType {
58 match (value.as_value(), rgx.as_value()) {
59 (Some(Value::String(s)), Some(Value::String(r))) => {
60 regex::Regex::new(format!("(?R)^({r})$").as_str())
61 .map(|r| r.is_match(s))
62 .map(Into::into)
63 .unwrap_or_default()
64 }
65 _ => LogicalType::False,
66 }
67}
68
69#[cfg(feature = "regex")]
70#[serde_json_path_macros::register(target = SEARCH_FUNC)]
71fn search(value: ValueType, rgx: ValueType) -> LogicalType {
72 match (value.as_value(), rgx.as_value()) {
73 (Some(Value::String(s)), Some(Value::String(r))) => {
74 regex::Regex::new(format!("(?R)({r})").as_str())
75 .map(|r| r.is_match(s))
76 .map(Into::into)
77 .unwrap_or_default()
78 }
79 _ => LogicalType::False,
80 }
81}
82
83#[serde_json_path_macros::register(target = VALUE_FUNC)]
84fn value(nodes: NodesType) -> ValueType {
85 if nodes.len() > 1 {
86 ValueType::Nothing
87 } else {
88 match nodes.first() {
89 Some(v) => ValueType::Node(v),
90 None => ValueType::Nothing,
91 }
92 }
93}