From 9d56db1f3e3ca1b3b7d3a60a4ad12154380ffc37 Mon Sep 17 00:00:00 2001 From: Thomas Cameron Date: Thu, 15 Jun 2023 02:33:47 +0900 Subject: [PATCH] Add serde support to document type. (#2616) ## Description Implements serde support for `Document`. ## Testing Test checks whether the serialized/de-serialized data matches with the expected value ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- rust-runtime/aws-smithy-types/src/document.rs | 78 +++++++++++++++++++ .../test_data/serialize_document.json | 43 ++++++++++ 2 files changed, 121 insertions(+) create mode 100644 rust-runtime/aws-smithy-types/test_data/serialize_document.json diff --git a/rust-runtime/aws-smithy-types/src/document.rs b/rust-runtime/aws-smithy-types/src/document.rs index a7c46d04db..2f13f895f8 100644 --- a/rust-runtime/aws-smithy-types/src/document.rs +++ b/rust-runtime/aws-smithy-types/src/document.rs @@ -7,6 +7,12 @@ use crate::Number; use std::borrow::Cow; use std::collections::HashMap; +#[cfg(any( + all(aws_sdk_unstable, feature = "serde-deserialize"), + all(aws_sdk_unstable, feature = "serde-serialize") +))] +use serde; + /* ANCHOR: document */ /// Document Type @@ -16,6 +22,21 @@ use std::collections::HashMap; /// modeled using rigid types, or data that has a schema that evolves outside of the purview of a model. /// The serialization format of a document is an implementation detail of a protocol. #[derive(Clone, Debug, PartialEq)] +#[cfg_attr( + all(aws_sdk_unstable, feature = "serde-serialize"), + derive(serde::Serialize) +)] +#[cfg_attr( + all(aws_sdk_unstable, feature = "serde-deserialize"), + derive(serde::Deserialize) +)] +#[cfg_attr( + any( + all(aws_sdk_unstable, feature = "serde-deserialize"), + all(aws_sdk_unstable, feature = "serde-serialize") + ), + serde(untagged) +)] pub enum Document { /// JSON object Object(HashMap), @@ -207,3 +228,60 @@ impl From for Document { Document::Number(value) } } + +/* ANCHOR END: document */ + +#[cfg(test)] +mod test { + /// checks if a) serialization of json suceeds and b) it is compatible with serde_json + #[test] + #[cfg(all( + aws_sdk_unstable, + feature = "serde-serialize", + feature = "serde-deserialize" + ))] + fn serialize_json() { + use crate::Document; + use crate::Number; + use std::collections::HashMap; + let mut map: HashMap = HashMap::new(); + // string + map.insert("hello".into(), "world".to_string().into()); + // numbers + map.insert("pos_int".into(), Document::Number(Number::PosInt(1).into())); + map.insert( + "neg_int".into(), + Document::Number(Number::NegInt(-1).into()), + ); + map.insert( + "float".into(), + Document::Number(Number::Float(0.1 + 0.2).into()), + ); + // booleans + map.insert("true".into(), true.into()); + map.insert("false".into(), false.into()); + // check if array with different datatypes would succeed + map.insert( + "array".into(), + vec![ + map.clone().into(), + "hello-world".to_string().into(), + true.into(), + false.into(), + ] + .into(), + ); + // map + map.insert("map".into(), map.clone().into()); + // null + map.insert("null".into(), Document::Null); + let obj = Document::Object(map); + // comparing string isnt going to work since there is no gurantee for the ordering of the keys + let target_file = include_str!("../test_data/serialize_document.json"); + let json: Result = serde_json::from_str(target_file); + // serializer + assert_eq!(serde_json::to_value(&obj).unwrap(), json.unwrap()); + let doc: Result = serde_json::from_str(target_file); + assert_eq!(obj, doc.unwrap()); + } +} diff --git a/rust-runtime/aws-smithy-types/test_data/serialize_document.json b/rust-runtime/aws-smithy-types/test_data/serialize_document.json new file mode 100644 index 0000000000..dcbac2986a --- /dev/null +++ b/rust-runtime/aws-smithy-types/test_data/serialize_document.json @@ -0,0 +1,43 @@ +{ + "null": null, + "true": true, + "pos_int": 1, + "false": false, + "map": { + "array": [ + { + "pos_int": 1, + "float": 0.30000000000000004, + "neg_int": -1, + "hello": "world", + "false": false, + "true": true + }, + "hello-world", + true, + false + ], + "pos_int": 1, + "float": 0.30000000000000004, + "neg_int": -1, + "hello": "world", + "false": false, + "true": true + }, + "float": 0.30000000000000004, + "neg_int": -1, + "hello": "world", + "array": [ + { + "pos_int": 1, + "float": 0.30000000000000004, + "neg_int": -1, + "hello": "world", + "false": false, + "true": true + }, + "hello-world", + true, + false + ] +}