AWS SDK

AWS SDK

rev. 39b55ba789d23348fd70aff57161c9e5dc302333

Files changed:

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-types/src/schema/serde/serializer.rs

@@ -0,1 +0,159 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Shape serialization interfaces for the Smithy data model.
           7  +
           8  +
use crate::schema::Schema;
           9  +
use crate::{BigDecimal, BigInteger, Blob, DateTime, Document};
          10  +
use std::error::Error;
          11  +
          12  +
/// Serializes Smithy shapes to a target format.
          13  +
///
          14  +
/// This trait provides a format-agnostic API for serializing the Smithy data model.
          15  +
/// Implementations serialize each data type to the corresponding encoding in their
          16  +
/// serial format (e.g., Smithy integers and floats to JSON numbers).
          17  +
///
          18  +
/// The serializer accepts a schema along with the value to provide additional
          19  +
/// information about how to serialize the value (e.g., timestamp format, JSON name).
          20  +
///
          21  +
/// # Type Parameter
          22  +
///
          23  +
/// * `Output` - The serialization target type (e.g., `Vec<u8>`, `String`)
          24  +
///
          25  +
/// # Example
          26  +
///
          27  +
/// ```ignore
          28  +
/// let mut serializer = JsonSerializer::new();
          29  +
/// serializer.write_string(&STRING_SCHEMA, "hello")?;
          30  +
/// let json_bytes = serializer.finish()?;
          31  +
/// ```
          32  +
pub trait ShapeSerializer {
          33  +
    /// The serialization target type (e.g., `Vec<u8>`, `String`).
          34  +
    type Output;
          35  +
          36  +
    /// The error type returned by serialization operations.
          37  +
    type Error: Error;
          38  +
          39  +
    /// Finalizes the serialization and returns the serialized output.
          40  +
    ///
          41  +
    /// This method should be called after all values have been written.
          42  +
    /// It may perform final formatting, validation, or resource cleanup.
          43  +
    fn finish(self) -> Result<Self::Output, Self::Error>;
          44  +
          45  +
    /// Writes a structure to the serializer.
          46  +
    ///
          47  +
    /// The structure serialization is driven by a callback that writes each member.
          48  +
    /// This avoids the need for trait objects while maintaining flexibility.
          49  +
    ///
          50  +
    /// # Arguments
          51  +
    ///
          52  +
    /// * `schema` - The schema of the structure being serialized
          53  +
    /// * `write_members` - Callback that writes the structure's members
          54  +
    fn write_struct<F>(&mut self, schema: &dyn Schema, write_members: F) -> Result<(), Self::Error>
          55  +
    where
          56  +
        F: FnOnce(&mut Self) -> Result<(), Self::Error>;
          57  +
          58  +
    /// Writes a list to the serializer.
          59  +
    ///
          60  +
    /// The list serialization is driven by a callback that writes each element.
          61  +
    ///
          62  +
    /// # Arguments
          63  +
    ///
          64  +
    /// * `schema` - The schema of the list being serialized
          65  +
    /// * `write_elements` - Callback that writes the list elements
          66  +
    fn write_list<F>(&mut self, schema: &dyn Schema, write_elements: F) -> Result<(), Self::Error>
          67  +
    where
          68  +
        F: FnOnce(&mut Self) -> Result<(), Self::Error>;
          69  +
          70  +
    /// Writes a map to the serializer.
          71  +
    ///
          72  +
    /// The map serialization is driven by a callback that writes each entry.
          73  +
    ///
          74  +
    /// # Arguments
          75  +
    ///
          76  +
    /// * `schema` - The schema of the map being serialized
          77  +
    /// * `write_entries` - Callback that writes the map entries
          78  +
    fn write_map<F>(&mut self, schema: &dyn Schema, write_entries: F) -> Result<(), Self::Error>
          79  +
    where
          80  +
        F: FnOnce(&mut Self) -> Result<(), Self::Error>;
          81  +
          82  +
    /// Writes a boolean value.
          83  +
    fn write_boolean(&mut self, schema: &dyn Schema, value: bool) -> Result<(), Self::Error>;
          84  +
          85  +
    /// Writes a byte (i8) value.
          86  +
    fn write_byte(&mut self, schema: &dyn Schema, value: i8) -> Result<(), Self::Error>;
          87  +
          88  +
    /// Writes a short (i16) value.
          89  +
    fn write_short(&mut self, schema: &dyn Schema, value: i16) -> Result<(), Self::Error>;
          90  +
          91  +
    /// Writes an integer (i32) value.
          92  +
    fn write_integer(&mut self, schema: &dyn Schema, value: i32) -> Result<(), Self::Error>;
          93  +
          94  +
    /// Writes a long (i64) value.
          95  +
    fn write_long(&mut self, schema: &dyn Schema, value: i64) -> Result<(), Self::Error>;
          96  +
          97  +
    /// Writes a float (f32) value.
          98  +
    fn write_float(&mut self, schema: &dyn Schema, value: f32) -> Result<(), Self::Error>;
          99  +
         100  +
    /// Writes a double (f64) value.
         101  +
    fn write_double(&mut self, schema: &dyn Schema, value: f64) -> Result<(), Self::Error>;
         102  +
         103  +
    /// Writes a big integer value.
         104  +
    fn write_big_integer(
         105  +
        &mut self,
         106  +
        schema: &dyn Schema,
         107  +
        value: &BigInteger,
         108  +
    ) -> Result<(), Self::Error>;
         109  +
         110  +
    /// Writes a big decimal value.
         111  +
    fn write_big_decimal(
         112  +
        &mut self,
         113  +
        schema: &dyn Schema,
         114  +
        value: &BigDecimal,
         115  +
    ) -> Result<(), Self::Error>;
         116  +
         117  +
    /// Writes a string value.
         118  +
    fn write_string(&mut self, schema: &dyn Schema, value: &str) -> Result<(), Self::Error>;
         119  +
         120  +
    /// Writes a blob (byte array) value.
         121  +
    fn write_blob(&mut self, schema: &dyn Schema, value: &Blob) -> Result<(), Self::Error>;
         122  +
         123  +
    /// Writes a timestamp value.
         124  +
    fn write_timestamp(&mut self, schema: &dyn Schema, value: &DateTime)
         125  +
        -> Result<(), Self::Error>;
         126  +
         127  +
    /// Writes a document value.
         128  +
    fn write_document(&mut self, schema: &dyn Schema, value: &Document) -> Result<(), Self::Error>;
         129  +
         130  +
    /// Writes a null value (for sparse collections).
         131  +
    fn write_null(&mut self, schema: &dyn Schema) -> Result<(), Self::Error>;
         132  +
}
         133  +
         134  +
/// Trait for structures that can be serialized.
         135  +
///
         136  +
/// This trait is implemented by generated structure types to enable
         137  +
/// schema-based serialization.
         138  +
///
         139  +
/// # Example
         140  +
///
         141  +
/// ```ignore
         142  +
/// impl SerializableStruct for MyStruct {
         143  +
///     fn serialize<S: ShapeSerializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
         144  +
///         serializer.write_struct(&Self::SCHEMA, |ser| {
         145  +
///             ser.write_string(&FIELD1_SCHEMA, &self.field1)?;
         146  +
///             ser.write_integer(&FIELD2_SCHEMA, self.field2)?;
         147  +
///             Ok(())
         148  +
///         })
         149  +
///     }
         150  +
/// }
         151  +
/// ```
         152  +
pub trait SerializableStruct {
         153  +
    /// Serializes this structure using the provided serializer.
         154  +
    ///
         155  +
    /// # Arguments
         156  +
    ///
         157  +
    /// * `serializer` - The serializer to write to
         158  +
    fn serialize<S: ShapeSerializer>(&self, serializer: &mut S) -> Result<(), S::Error>;
         159  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-types/src/schema/shape_id.rs

@@ -0,1 +0,163 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
/// A Smithy Shape ID.
           7  +
///
           8  +
/// Shape IDs uniquely identify shapes in a Smithy model.
           9  +
/// Format: `namespace#shapeName` or `namespace#shapeName$memberName`
          10  +
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
          11  +
pub struct ShapeId {
          12  +
    value: &'static str,
          13  +
}
          14  +
          15  +
impl ShapeId {
          16  +
    /// Creates a ShapeId from a static string at compile time.
          17  +
    ///
          18  +
    /// This is used for const initialization of prelude schemas.
          19  +
    pub const fn from_static(value: &'static str) -> Self {
          20  +
        Self { value }
          21  +
    }
          22  +
          23  +
    /// Creates a new ShapeId from a string.
          24  +
    ///
          25  +
    /// # Examples
          26  +
    /// ```
          27  +
    /// use aws_smithy_types::schema::ShapeId;
          28  +
    ///
          29  +
    /// let shape_id = ShapeId::new("smithy.api#String");
          30  +
    /// ```
          31  +
    pub fn new(value: impl Into<String>) -> Self {
          32  +
        // Leak the string to get a 'static reference
          33  +
        Self {
          34  +
            value: Box::leak(value.into().into_boxed_str()),
          35  +
        }
          36  +
    }
          37  +
          38  +
    /// Returns the string representation of this ShapeId.
          39  +
    pub fn as_str(&self) -> &str {
          40  +
        self.value
          41  +
    }
          42  +
          43  +
    /// Returns the namespace portion of the ShapeId.
          44  +
    ///
          45  +
    /// # Examples
          46  +
    /// ```
          47  +
    /// use aws_smithy_types::schema::ShapeId;
          48  +
    ///
          49  +
    /// let shape_id = ShapeId::from_static("smithy.api#String");
          50  +
    /// assert_eq!(shape_id.namespace(), Some("smithy.api"));
          51  +
    /// ```
          52  +
    pub fn namespace(&self) -> Option<&str> {
          53  +
        self.value.split_once('#').map(|(ns, _)| ns)
          54  +
    }
          55  +
          56  +
    /// Returns the shape name portion of the ShapeId.
          57  +
    ///
          58  +
    /// # Examples
          59  +
    /// ```
          60  +
    /// use aws_smithy_types::schema::ShapeId;
          61  +
    ///
          62  +
    /// let shape_id = ShapeId::from_static("smithy.api#String");
          63  +
    /// assert_eq!(shape_id.shape_name(), Some("String"));
          64  +
    /// ```
          65  +
    pub fn shape_name(&self) -> Option<&str> {
          66  +
        self.value
          67  +
            .split_once('#')
          68  +
            .and_then(|(_, rest)| rest.split_once('$').map(|(name, _)| name).or(Some(rest)))
          69  +
    }
          70  +
          71  +
    /// Returns the member name if this is a member shape ID.
          72  +
    ///
          73  +
    /// # Examples
          74  +
    /// ```
          75  +
    /// use aws_smithy_types::schema::ShapeId;
          76  +
    ///
          77  +
    /// let shape_id = ShapeId::new("com.example#MyStruct$member");
          78  +
    /// assert_eq!(shape_id.member_name(), Some("member"));
          79  +
    /// ```
          80  +
    pub fn member_name(&self) -> Option<&str> {
          81  +
        self.value
          82  +
            .split_once('#')
          83  +
            .and_then(|(_, rest)| rest.split_once('$').map(|(_, member)| member))
          84  +
    }
          85  +
}
          86  +
          87  +
impl From<String> for ShapeId {
          88  +
    fn from(value: String) -> Self {
          89  +
        Self::new(value)
          90  +
    }
          91  +
}
          92  +
          93  +
impl From<&str> for ShapeId {
          94  +
    fn from(value: &str) -> Self {
          95  +
        Self::new(value)
          96  +
    }
          97  +
}
          98  +
          99  +
#[cfg(test)]
         100  +
mod tests {
         101  +
    use super::*;
         102  +
         103  +
    #[test]
         104  +
    fn test_new() {
         105  +
        let shape_id = ShapeId::new("smithy.api#String");
         106  +
        assert_eq!(shape_id.as_str(), "smithy.api#String");
         107  +
    }
         108  +
         109  +
    #[test]
         110  +
    fn test_namespace() {
         111  +
        assert_eq!(
         112  +
            ShapeId::new("smithy.api#String").namespace(),
         113  +
            Some("smithy.api")
         114  +
        );
         115  +
        assert_eq!(
         116  +
            ShapeId::new("com.example#MyStruct$member").namespace(),
         117  +
            Some("com.example")
         118  +
        );
         119  +
        assert_eq!(ShapeId::new("NoNamespace").namespace(), None);
         120  +
    }
         121  +
         122  +
    #[test]
         123  +
    fn test_shape_name() {
         124  +
        assert_eq!(
         125  +
            ShapeId::new("smithy.api#String").shape_name(),
         126  +
            Some("String")
         127  +
        );
         128  +
        assert_eq!(
         129  +
            ShapeId::new("com.example#MyStruct$member").shape_name(),
         130  +
            Some("MyStruct")
         131  +
        );
         132  +
        assert_eq!(ShapeId::new("NoNamespace").shape_name(), None);
         133  +
    }
         134  +
         135  +
    #[test]
         136  +
    fn test_member_name() {
         137  +
        assert_eq!(
         138  +
            ShapeId::new("com.example#MyStruct$member").member_name(),
         139  +
            Some("member")
         140  +
        );
         141  +
        assert_eq!(ShapeId::new("smithy.api#String").member_name(), None);
         142  +
        assert_eq!(ShapeId::new("NoNamespace").member_name(), None);
         143  +
    }
         144  +
         145  +
    #[test]
         146  +
    fn test_from_string() {
         147  +
        let shape_id: ShapeId = String::from("smithy.api#String").into();
         148  +
        assert_eq!(shape_id.as_str(), "smithy.api#String");
         149  +
    }
         150  +
         151  +
    #[test]
         152  +
    fn test_from_str() {
         153  +
        let shape_id: ShapeId = "smithy.api#String".into();
         154  +
        assert_eq!(shape_id.as_str(), "smithy.api#String");
         155  +
    }
         156  +
         157  +
    #[test]
         158  +
    fn test_clone_and_equality() {
         159  +
        let shape_id1 = ShapeId::new("smithy.api#String");
         160  +
        let shape_id2 = shape_id1.clone();
         161  +
        assert_eq!(shape_id1, shape_id2);
         162  +
    }
         163  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-types/src/schema/shape_type.rs

@@ -0,1 +0,89 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
/// Enumeration of Smithy shape types.
           7  +
///
           8  +
/// This represents the core shape types from the Smithy specification,
           9  +
/// including simple types, aggregate types, and the special member type.
          10  +
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
          11  +
#[non_exhaustive]
          12  +
pub enum ShapeType {
          13  +
    // Simple types
          14  +
    /// Boolean type
          15  +
    Boolean,
          16  +
    /// 8-bit signed integer
          17  +
    Byte,
          18  +
    /// 16-bit signed integer
          19  +
    Short,
          20  +
    /// 32-bit signed integer
          21  +
    Integer,
          22  +
    /// 64-bit signed integer
          23  +
    Long,
          24  +
    /// 32-bit floating point
          25  +
    Float,
          26  +
    /// 64-bit floating point
          27  +
    Double,
          28  +
    /// Arbitrary precision integer
          29  +
    BigInteger,
          30  +
    /// Arbitrary precision decimal
          31  +
    BigDecimal,
          32  +
    /// UTF-8 string
          33  +
    String,
          34  +
    /// Binary data
          35  +
    Blob,
          36  +
    /// Timestamp
          37  +
    Timestamp,
          38  +
    /// Document type
          39  +
    Document,
          40  +
          41  +
    // Aggregate types
          42  +
    /// List type
          43  +
    List,
          44  +
    /// Map type
          45  +
    Map,
          46  +
    /// Structure type
          47  +
    Structure,
          48  +
    /// Union type
          49  +
    Union,
          50  +
          51  +
    // Member
          52  +
    /// Member shape
          53  +
    Member,
          54  +
}
          55  +
          56  +
impl ShapeType {
          57  +
    /// Returns true if this is a simple type.
          58  +
    #[inline]
          59  +
    pub fn is_simple(&self) -> bool {
          60  +
        matches!(
          61  +
            self,
          62  +
            Self::Boolean
          63  +
                | Self::Byte
          64  +
                | Self::Short
          65  +
                | Self::Integer
          66  +
                | Self::Long
          67  +
                | Self::Float
          68  +
                | Self::Double
          69  +
                | Self::BigInteger
          70  +
                | Self::BigDecimal
          71  +
                | Self::String
          72  +
                | Self::Blob
          73  +
                | Self::Timestamp
          74  +
                | Self::Document
          75  +
        )
          76  +
    }
          77  +
          78  +
    /// Returns true if this is an aggregate type.
          79  +
    #[inline]
          80  +
    pub fn is_aggregate(&self) -> bool {
          81  +
        matches!(self, Self::List | Self::Map | Self::Structure | Self::Union)
          82  +
    }
          83  +
          84  +
    /// Returns true if this is a member type.
          85  +
    #[inline]
          86  +
    pub fn is_member(&self) -> bool {
          87  +
        matches!(self, Self::Member)
          88  +
    }
          89  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-types/src/schema/trait_map.rs

@@ -0,1 +0,75 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
use super::{ShapeId, Trait};
           7  +
use std::collections::HashMap;
           8  +
           9  +
/// A map of traits keyed by their Shape ID.
          10  +
///
          11  +
/// This provides efficient lookup of traits during serialization and deserialization.
          12  +
#[derive(Debug)]
          13  +
pub struct TraitMap {
          14  +
    traits: Option<HashMap<ShapeId, Box<dyn Trait>>>,
          15  +
}
          16  +
          17  +
impl Default for TraitMap {
          18  +
    fn default() -> Self {
          19  +
        Self::new()
          20  +
    }
          21  +
}
          22  +
          23  +
impl TraitMap {
          24  +
    /// Creates a new empty TraitMap.
          25  +
    pub fn new() -> Self {
          26  +
        Self {
          27  +
            traits: Some(HashMap::new()),
          28  +
        }
          29  +
    }
          30  +
          31  +
    /// Creates an empty TraitMap for const contexts.
          32  +
    pub const fn empty() -> Self {
          33  +
        Self { traits: None }
          34  +
    }
          35  +
          36  +
    /// Inserts a trait into the map.
          37  +
    pub fn insert(&mut self, trait_obj: Box<dyn Trait>) {
          38  +
        if self.traits.is_none() {
          39  +
            self.traits = Some(HashMap::new());
          40  +
        }
          41  +
        let id = trait_obj.trait_id().clone();
          42  +
        self.traits.as_mut().unwrap().insert(id, trait_obj);
          43  +
    }
          44  +
          45  +
    /// Gets a trait by its Shape ID.
          46  +
    pub fn get(&self, id: &ShapeId) -> Option<&dyn Trait> {
          47  +
        self.traits.as_ref()?.get(id).map(|t| t.as_ref())
          48  +
    }
          49  +
          50  +
    /// Returns true if the map contains a trait with the given Shape ID.
          51  +
    pub fn contains(&self, id: &ShapeId) -> bool {
          52  +
        self.traits
          53  +
            .as_ref()
          54  +
            .map(|m| m.contains_key(id))
          55  +
            .unwrap_or(false)
          56  +
    }
          57  +
          58  +
    /// Returns an iterator over all traits.
          59  +
    pub fn iter(&self) -> impl Iterator<Item = &dyn Trait> {
          60  +
        self.traits
          61  +
            .as_ref()
          62  +
            .into_iter()
          63  +
            .flat_map(|m| m.values().map(|t| t.as_ref()))
          64  +
    }
          65  +
          66  +
    /// Returns the number of traits in the map.
          67  +
    pub fn len(&self) -> usize {
          68  +
        self.traits.as_ref().map(|m| m.len()).unwrap_or(0)
          69  +
    }
          70  +
          71  +
    /// Returns true if the map is empty.
          72  +
    pub fn is_empty(&self) -> bool {
          73  +
        self.traits.as_ref().map(|m| m.is_empty()).unwrap_or(true)
          74  +
    }
          75  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-types/src/schema/trait_type.rs

@@ -0,1 +0,20 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
use super::ShapeId;
           7  +
use std::any::Any;
           8  +
use std::fmt;
           9  +
          10  +
/// Trait representing a Smithy trait at runtime.
          11  +
///
          12  +
/// Traits provide additional metadata about shapes that affect serialization,
          13  +
/// validation, and other behaviors.
          14  +
pub trait Trait: Any + Send + Sync + fmt::Debug {
          15  +
    /// Returns the Shape ID of this trait.
          16  +
    fn trait_id(&self) -> &ShapeId;
          17  +
          18  +
    /// Returns this trait as `&dyn Any` for downcasting.
          19  +
    fn as_any(&self) -> &dyn Any;
          20  +
}