json_predicate/predicate/second_order/
or.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 Or {
21 #[builder(default)]
24 pub path: Option<JSONPath>,
25 pub apply: Vec<Predicate>,
26}
27
28impl Serialize for Or {
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("Or", 3)?;
34 state.serialize_field("op", "or")?;
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 Or {
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 VisitorOr<'de> {
85 marker: PhantomData<Or>,
86 lifetime: PhantomData<&'de ()>,
87 }
88
89 impl<'de> Visitor<'de> for VisitorOr<'de> {
90 type Value = Or;
91 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
92 formatter.write_str("Or")
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() != "or" {
133 return Err(serde::de::Error::custom("`op` should be `or`"));
134 }
135
136 Ok(Or { apply, path })
137 }
138 }
139
140 const FIELDS: &[&str] = &["op", "apply", "path"];
141 Deserializer::deserialize_struct(
142 deserializer,
143 "Or",
144 FIELDS,
145 VisitorOr {
146 marker: PhantomData::<Or>,
147 lifetime: PhantomData,
148 },
149 )
150 }
151}
152
153impl From<Or> for SecondOrder {
154 fn from(value: Or) -> Self {
155 SecondOrder::Or(value)
156 }
157}
158
159impl PredicateImpl for Or {
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 let mut acc = true;
165
166 for ap in &self.apply {
167 let pred = ap.evaluate(data, ctx.clone());
168
169 if pred.is_ok() {
170 return Ok(true);
171 } else {
172 acc = false;
173 }
174 }
175
176 Ok(acc)
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use serde::Deserialize;
183
184 use crate::predicate::second_order::or::Or;
185
186 #[test]
187 fn deser_test() {
188 let or_expect = serde_json::json!({
189 "op": "or",
190 "apply": [
191 {
192 "op": "defined",
193 "path": "/a/b"
194 },
195 {
196 "op": "less",
197 "path": "/a/c/d",
198 "value": 15
199 }
200 ]
201 });
202
203 let deser = Or::deserialize(or_expect).unwrap();
204
205 insta::assert_json_snapshot!(deser);
206 }
207}