json_predicate/predicate/first_order/
defined.rs

1use 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/// The "defined" predicate evaluates as true if the referenced element exists
14/// within the target context.
15#[derive(Debug, Builder, Clone, PartialEq, Eq)]
16#[builder(pattern = "owned", setter(into, strip_option))]
17pub struct Defined {
18    /// Must be a [JSON Pointer](https://tools.ietf.org/html/rfc6901)
19    /// If the "path" member is not specified within the predicate object, it's value is assumed to be an empty string.
20    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        // The "defined" predicate evaluates as true if the referenced element
151        // exists within the target context.
152        //
153        // If the element doesn't exist we woulnd't be here so even if
154        // it's null, it's enough to tell it exists.
155        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}