aws_smithy_types/
document.rs
1use crate::Number;
7use std::borrow::Cow;
8use std::collections::HashMap;
9
10#[cfg(any(
11 all(aws_sdk_unstable, feature = "serde-deserialize"),
12 all(aws_sdk_unstable, feature = "serde-serialize")
13))]
14use serde;
15
16#[derive(Clone, Debug, PartialEq)]
25#[cfg_attr(
26 all(aws_sdk_unstable, feature = "serde-serialize"),
27 derive(serde::Serialize)
28)]
29#[cfg_attr(
30 all(aws_sdk_unstable, feature = "serde-deserialize"),
31 derive(serde::Deserialize)
32)]
33#[cfg_attr(
34 any(
35 all(aws_sdk_unstable, feature = "serde-deserialize"),
36 all(aws_sdk_unstable, feature = "serde-serialize")
37 ),
38 serde(untagged)
39)]
40pub enum Document {
41 Object(HashMap<String, Document>),
43 Array(Vec<Document>),
45 Number(Number),
47 String(String),
49 Bool(bool),
51 Null,
53}
54
55impl Document {
56 pub fn as_object(&self) -> Option<&HashMap<String, Document>> {
58 if let Self::Object(object) = self {
59 Some(object)
60 } else {
61 None
62 }
63 }
64
65 pub fn as_object_mut(&mut self) -> Option<&mut HashMap<String, Document>> {
67 if let Self::Object(object) = self {
68 Some(object)
69 } else {
70 None
71 }
72 }
73
74 pub fn as_array(&self) -> Option<&Vec<Document>> {
76 if let Self::Array(array) = self {
77 Some(array)
78 } else {
79 None
80 }
81 }
82
83 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Document>> {
85 if let Self::Array(array) = self {
86 Some(array)
87 } else {
88 None
89 }
90 }
91
92 pub fn as_number(&self) -> Option<&Number> {
94 if let Self::Number(number) = self {
95 Some(number)
96 } else {
97 None
98 }
99 }
100
101 pub fn as_string(&self) -> Option<&str> {
103 if let Self::String(string) = self {
104 Some(string)
105 } else {
106 None
107 }
108 }
109
110 pub fn as_bool(&self) -> Option<bool> {
112 if let Self::Bool(boolean) = self {
113 Some(*boolean)
114 } else {
115 None
116 }
117 }
118
119 pub fn as_null(&self) -> Option<()> {
121 if let Self::Null = self {
122 Some(())
123 } else {
124 None
125 }
126 }
127
128 pub fn is_object(&self) -> bool {
130 matches!(self, Self::Object(_))
131 }
132
133 pub fn is_array(&self) -> bool {
135 matches!(self, Self::Array(_))
136 }
137
138 pub fn is_number(&self) -> bool {
140 matches!(self, Self::Number(_))
141 }
142
143 pub fn is_string(&self) -> bool {
145 matches!(self, Self::String(_))
146 }
147
148 pub fn is_bool(&self) -> bool {
150 matches!(self, Self::Bool(_))
151 }
152
153 pub fn is_null(&self) -> bool {
155 matches!(self, Self::Null)
156 }
157}
158
159impl Default for Document {
161 fn default() -> Self {
162 Self::Null
163 }
164}
165
166impl From<bool> for Document {
167 fn from(value: bool) -> Self {
168 Document::Bool(value)
169 }
170}
171
172impl<'a> From<&'a str> for Document {
173 fn from(value: &'a str) -> Self {
174 Document::String(value.to_string())
175 }
176}
177
178impl<'a> From<Cow<'a, str>> for Document {
179 fn from(value: Cow<'a, str>) -> Self {
180 Document::String(value.into_owned())
181 }
182}
183
184impl From<String> for Document {
185 fn from(value: String) -> Self {
186 Document::String(value)
187 }
188}
189
190impl From<Vec<Document>> for Document {
191 fn from(values: Vec<Document>) -> Self {
192 Document::Array(values)
193 }
194}
195
196impl From<HashMap<String, Document>> for Document {
197 fn from(values: HashMap<String, Document>) -> Self {
198 Document::Object(values)
199 }
200}
201
202impl From<u64> for Document {
203 fn from(value: u64) -> Self {
204 Document::Number(Number::PosInt(value))
205 }
206}
207
208impl From<i64> for Document {
209 fn from(value: i64) -> Self {
210 Document::Number(Number::NegInt(value))
211 }
212}
213
214impl From<i32> for Document {
215 fn from(value: i32) -> Self {
216 Document::Number(Number::NegInt(value as i64))
217 }
218}
219
220impl From<f64> for Document {
221 fn from(value: f64) -> Self {
222 Document::Number(Number::Float(value))
223 }
224}
225
226impl From<Number> for Document {
227 fn from(value: Number) -> Self {
228 Document::Number(value)
229 }
230}
231
232#[cfg(test)]
235mod test {
236 #[test]
238 #[cfg(all(
239 aws_sdk_unstable,
240 feature = "serde-serialize",
241 feature = "serde-deserialize"
242 ))]
243 fn serialize_json() {
244 use crate::Document;
245 use crate::Number;
246 use std::collections::HashMap;
247 let mut map: HashMap<String, Document> = HashMap::new();
248 map.insert("hello".into(), "world".to_string().into());
250 map.insert("pos_int".into(), Document::Number(Number::PosInt(1).into()));
252 map.insert(
253 "neg_int".into(),
254 Document::Number(Number::NegInt(-1).into()),
255 );
256 map.insert(
257 "float".into(),
258 Document::Number(Number::Float(0.1 + 0.2).into()),
259 );
260 map.insert("true".into(), true.into());
262 map.insert("false".into(), false.into());
263 map.insert(
265 "array".into(),
266 vec![
267 map.clone().into(),
268 "hello-world".to_string().into(),
269 true.into(),
270 false.into(),
271 ]
272 .into(),
273 );
274 map.insert("map".into(), map.clone().into());
276 map.insert("null".into(), Document::Null);
278 let obj = Document::Object(map);
279 let target_file = include_str!("../test_data/serialize_document.json");
281 let json: Result<serde_json::Value, _> = serde_json::from_str(target_file);
282 assert_eq!(serde_json::to_value(&obj).unwrap(), json.unwrap());
284 let doc: Result<Document, _> = serde_json::from_str(target_file);
285 assert_eq!(obj, doc.unwrap());
286 }
287}