cedar_policy_core/
jsonvalue.rs

1/*
2 * Copyright Cedar Contributors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! This module provides general-purpose JSON utilities not specific to Cedar.
18
19use serde::de::{MapAccess, SeqAccess, Visitor};
20use serde::{Deserialize, Serialize};
21
22/// Wrapper around `serde_json::Value`, with a different `Deserialize`
23/// implementation, such that duplicate keys in JSON objects (maps/records) are
24/// not allowed (result in an error).
25//
26// CAUTION: this type is publicly exported in `cedar-policy`.
27// Don't make fields `pub`, don't make breaking changes, and use caution
28// when adding public methods.
29#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
30pub struct JsonValueWithNoDuplicateKeys(serde_json::Value);
31
32impl std::ops::Deref for JsonValueWithNoDuplicateKeys {
33    type Target = serde_json::Value;
34    fn deref(&self) -> &Self::Target {
35        &self.0
36    }
37}
38
39// this implementation heavily borrows from the `Deserialize` implementation
40// for `serde_json::Value`
41impl<'de> Deserialize<'de> for JsonValueWithNoDuplicateKeys {
42    fn deserialize<D>(deserializer: D) -> Result<JsonValueWithNoDuplicateKeys, D::Error>
43    where
44        D: serde::Deserializer<'de>,
45    {
46        struct ValueVisitor;
47
48        impl<'de> Visitor<'de> for ValueVisitor {
49            type Value = JsonValueWithNoDuplicateKeys;
50
51            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52                formatter.write_str("any valid JSON value")
53            }
54
55            fn visit_bool<E>(self, value: bool) -> Result<JsonValueWithNoDuplicateKeys, E> {
56                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Bool(value)))
57            }
58
59            fn visit_i64<E>(self, value: i64) -> Result<JsonValueWithNoDuplicateKeys, E> {
60                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Number(
61                    value.into(),
62                )))
63            }
64
65            fn visit_u64<E>(self, value: u64) -> Result<JsonValueWithNoDuplicateKeys, E> {
66                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Number(
67                    value.into(),
68                )))
69            }
70
71            fn visit_f64<E>(self, value: f64) -> Result<JsonValueWithNoDuplicateKeys, E> {
72                Ok(JsonValueWithNoDuplicateKeys(
73                    serde_json::Number::from_f64(value)
74                        .map_or(serde_json::Value::Null, serde_json::Value::Number),
75                ))
76            }
77
78            fn visit_str<E>(self, value: &str) -> Result<JsonValueWithNoDuplicateKeys, E>
79            where
80                E: serde::de::Error,
81            {
82                self.visit_string(String::from(value))
83            }
84
85            fn visit_string<E>(self, value: String) -> Result<JsonValueWithNoDuplicateKeys, E> {
86                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::String(
87                    value,
88                )))
89            }
90
91            fn visit_none<E>(self) -> Result<JsonValueWithNoDuplicateKeys, E> {
92                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Null))
93            }
94
95            fn visit_some<D>(
96                self,
97                deserializer: D,
98            ) -> Result<JsonValueWithNoDuplicateKeys, D::Error>
99            where
100                D: serde::Deserializer<'de>,
101            {
102                Deserialize::deserialize(deserializer)
103            }
104
105            fn visit_unit<E>(self) -> Result<JsonValueWithNoDuplicateKeys, E> {
106                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Null))
107            }
108
109            fn visit_seq<A>(self, mut access: A) -> Result<JsonValueWithNoDuplicateKeys, A::Error>
110            where
111                A: SeqAccess<'de>,
112            {
113                let mut vec: Vec<serde_json::Value> = Vec::new();
114
115                while let Some(elem) = access.next_element::<JsonValueWithNoDuplicateKeys>()? {
116                    vec.push(elem.0);
117                }
118
119                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Array(vec)))
120            }
121
122            fn visit_map<A>(self, mut access: A) -> Result<JsonValueWithNoDuplicateKeys, A::Error>
123            where
124                A: MapAccess<'de>,
125            {
126                let mut map: serde_json::Map<String, serde_json::Value> = serde_json::Map::new();
127
128                while let Some((k, v)) =
129                    access.next_entry::<String, JsonValueWithNoDuplicateKeys>()?
130                {
131                    match map.entry(k) {
132                        serde_json::map::Entry::Vacant(ventry) => {
133                            ventry.insert(v.0);
134                        }
135                        serde_json::map::Entry::Occupied(oentry) => {
136                            return Err(serde::de::Error::custom(format!(
137                                "the key `{}` occurs two or more times in the same JSON object",
138                                oentry.key()
139                            )));
140                        }
141                    }
142                }
143
144                Ok(JsonValueWithNoDuplicateKeys(serde_json::Value::Object(map)))
145            }
146        }
147
148        deserializer.deserialize_any(ValueVisitor)
149    }
150}
151
152impl std::str::FromStr for JsonValueWithNoDuplicateKeys {
153    type Err = serde_json::Error;
154    fn from_str(s: &str) -> Result<Self, Self::Err> {
155        serde_json::from_str(s)
156    }
157}
158
159impl From<serde_json::Value> for JsonValueWithNoDuplicateKeys {
160    fn from(value: serde_json::Value) -> Self {
161        // the `serde_json::Value` representation cannot represent duplicate keys, so we can just wrap.
162        // If there were any duplicate keys, they're already gone as a result of creating the `serde_json::Value`.
163        Self(value)
164    }
165}
166
167impl From<JsonValueWithNoDuplicateKeys> for serde_json::Value {
168    fn from(value: JsonValueWithNoDuplicateKeys) -> Self {
169        value.0
170    }
171}