Unverified Commit 9d56db1f authored by Thomas Cameron's avatar Thomas Cameron Committed by GitHub
Browse files

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._
parent 1e2c03c9
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -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<String, Document>),
@@ -207,3 +228,60 @@ impl From<Number> 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<String, Document> = 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::Value, _> = serde_json::from_str(target_file);
        // serializer
        assert_eq!(serde_json::to_value(&obj).unwrap(), json.unwrap());
        let doc: Result<Document, _> = serde_json::from_str(target_file);
        assert_eq!(obj, doc.unwrap());
    }
}
+43 −0
Original line number Diff line number Diff line
{
    "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
    ]
}