json_predicate/predicate/second_order/
and.rs1use derive_builder::Builder;
2use serde_json::Value;
3use std::marker::PhantomData;
4
5use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor};
6use serde::{ser::SerializeStruct, Serialize};
7
8use crate::json_path::JSONPath;
9use crate::predicate::context::PredicateContext;
10use crate::predicate::error::PredicateError;
11use crate::predicate::PredicateImpl;
12use crate::Predicate;
13
14use super::SecondOrder;
15
16#[derive(Debug, Clone, PartialEq, Eq, Builder)]
19#[builder(pattern = "owned", setter(into, strip_option))]
20pub struct And {
21 #[builder(default)]
24 pub path: Option<JSONPath>,
25 pub apply: Vec<Predicate>,
26}
27
28impl Serialize for And {
29 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30 where
31 S: serde::Serializer,
32 {
33 let mut state = serializer.serialize_struct("And", 3)?;
34 state.serialize_field("op", "and")?;
35 state.serialize_field("path", &self.path)?;
36 state.serialize_field("apply", &self.apply)?;
37 state.end()
38 }
39}
40
41impl<'de> Deserialize<'de> for And {
42 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
43 where
44 D: Deserializer<'de>,
45 {
46 #[allow(non_camel_case_types)]
47 enum Field {
48 op,
49 path,
50 apply,
51 __ignore,
52 }
53 struct FieldVisitor;
54
55 impl<'de> Visitor<'de> for FieldVisitor {
56 type Value = Field;
57 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
58 formatter.write_str("field identifier")
59 }
60
61 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
62 where
63 E: de::Error,
64 {
65 match value {
66 "op" => Ok(Field::op),
67 "apply" => Ok(Field::apply),
68 "path" => Ok(Field::path),
69 _ => Ok(Field::__ignore),
70 }
71 }
72 }
73
74 impl<'de> Deserialize<'de> for Field {
75 #[inline]
76 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77 where
78 D: Deserializer<'de>,
79 {
80 Deserializer::deserialize_identifier(deserializer, FieldVisitor)
81 }
82 }
83
84 struct VisitorAnd<'de> {
85 marker: PhantomData<And>,
86 lifetime: PhantomData<&'de ()>,
87 }
88
89 impl<'de> Visitor<'de> for VisitorAnd<'de> {
90 type Value = And;
91 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
92 formatter.write_str("And")
93 }
94
95 #[inline]
96 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
97 where
98 A: MapAccess<'de>,
99 {
100 let mut path: Option<Option<JSONPath>> = None;
101 let mut apply: Option<Vec<Predicate>> = None;
102 let mut op: Option<String> = None;
103
104 while let Some(key) = MapAccess::next_key::<Field>(&mut map)? {
105 match key {
106 Field::op => {
107 if op.is_some() {
108 return Err(serde::de::Error::duplicate_field("op"));
109 }
110 op = Some(MapAccess::next_value::<String>(&mut map)?);
111 }
112 Field::path => {
113 if path.is_some() {
114 return Err(serde::de::Error::duplicate_field("path"));
115 }
116 path = Some(MapAccess::next_value::<Option<JSONPath>>(&mut map)?);
117 }
118 Field::apply => {
119 if apply.is_some() {
120 return Err(serde::de::Error::duplicate_field("value"));
121 }
122 apply = Some(MapAccess::next_value::<Vec<Predicate>>(&mut map)?);
123 }
124 Field::__ignore => {}
125 }
126 }
127
128 let path = path.flatten();
129 let apply = apply.ok_or(serde::de::Error::missing_field("apply"))?;
130 let op = op.ok_or(serde::de::Error::missing_field("op"))?;
131
132 if op.as_str() != "and" {
133 return Err(serde::de::Error::custom("`op` should be `and`"));
134 }
135
136 Ok(And { apply, path })
137 }
138 }
139
140 const FIELDS: &[&str] = &["op", "apply", "path"];
141 Deserializer::deserialize_struct(
142 deserializer,
143 "And",
144 FIELDS,
145 VisitorAnd {
146 marker: PhantomData::<And>,
147 lifetime: PhantomData,
148 },
149 )
150 }
151}
152
153impl From<And> for SecondOrder {
154 fn from(value: And) -> Self {
155 SecondOrder::And(value)
156 }
157}
158
159impl PredicateImpl for And {
160 fn evaluate(&self, data: &Value, ctx: PredicateContext) -> Result<bool, PredicateError> {
161 let path = ctx.final_path(&self.path);
162 let ctx = PredicateContext::from(path);
163
164 for ap in &self.apply {
165 let pred = ap.evaluate(data, ctx.clone());
166
167 if pred.is_ok() {
168 continue;
169 } else {
170 return pred;
171 }
172 }
173
174 Ok(true)
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use serde::Deserialize;
181
182 use crate::predicate::second_order::and::And;
183
184 #[test]
185 fn deser_test() {
186 let and_expect = serde_json::json!({
187 "op": "and",
188 "apply": [
189 {
190 "op": "defined",
191 "path": "/a/b"
192 },
193 {
194 "op": "less",
195 "path": "/a/c/d",
196 "value": 15
197 }
198 ]
199 });
200
201 let deser = And::deserialize(and_expect).unwrap();
202
203 insta::assert_json_snapshot!(deser);
204 }
205}