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