aws_smithy_schema/schema/serde/
deserializer.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Shape deserialization interfaces for the Smithy data model.
7
8use crate::Schema;
9use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime, Document};
10use std::error::Error;
11
12/// Deserializes Smithy shapes from a serial format.
13///
14/// This trait provides a format-agnostic API for deserializing the Smithy data model.
15/// Implementations read from a serial format and create data objects based on schemas.
16///
17/// The deserializer uses a consumer pattern for aggregate types (structures, lists, maps)
18/// to avoid trait object limitations and enable efficient deserialization without
19/// intermediate allocations.
20///
21/// # Consumer Pattern
22///
23/// For aggregate types, the deserializer calls a consumer function for each element/member.
24/// The consumer receives mutable state and updates it with each deserialized value.
25/// This pattern:
26/// - Avoids trait object issues with generic methods
27/// - Enables zero-cost abstractions (closures can be inlined)
28/// - Allows caller to control deserialization order and state management
29/// - Matches the SEP's recommendation for compiled typed languages
30///
31/// # Example
32///
33/// ```ignore
34/// // Deserializing a structure
35/// let mut builder = MyStructBuilder::default();
36/// deserializer.read_struct(
37///     &MY_STRUCT_SCHEMA,
38///     builder,
39///     |mut builder, member, deser| {
40///         match member.member_index() {
41///             0 => builder.field1 = Some(deser.read_string(member)?),
42///             1 => builder.field2 = Some(deser.read_i32(member)?),
43///             _ => {}
44///         }
45///         Ok(builder)
46///     },
47/// )?;
48/// let my_struct = builder.build();
49/// ```
50pub trait ShapeDeserializer {
51    /// The error type returned by deserialization operations.
52    type Error: Error;
53
54    /// Reads a structure from the deserializer.
55    ///
56    /// The structure deserialization is driven by a consumer callback that is called
57    /// for each member. The consumer receives the current state, the member schema,
58    /// and the deserializer, and returns the updated state.
59    ///
60    /// # Arguments
61    ///
62    /// * `schema` - The schema of the structure being deserialized
63    /// * `state` - Initial state (typically a builder)
64    /// * `consumer` - Callback invoked for each member with (state, member_schema, deserializer)
65    ///
66    /// # Returns
67    ///
68    /// The final state after processing all members
69    fn read_struct<T, F>(
70        &mut self,
71        schema: &dyn Schema,
72        state: T,
73        consumer: F,
74    ) -> Result<T, Self::Error>
75    where
76        F: FnMut(T, &dyn Schema, &mut Self) -> Result<T, Self::Error>;
77
78    /// Reads a list from the deserializer.
79    ///
80    /// The list deserialization is driven by a consumer callback that is called
81    /// for each element. The consumer receives the current state and the deserializer,
82    /// and returns the updated state.
83    ///
84    /// # Arguments
85    ///
86    /// * `schema` - The schema of the list being deserialized
87    /// * `state` - Initial state (typically a Vec or collection)
88    /// * `consumer` - Callback invoked for each element with (state, deserializer)
89    ///
90    /// # Returns
91    ///
92    /// The final state after processing all elements
93    fn read_list<T, F>(
94        &mut self,
95        schema: &dyn Schema,
96        state: T,
97        consumer: F,
98    ) -> Result<T, Self::Error>
99    where
100        F: FnMut(T, &mut Self) -> Result<T, Self::Error>;
101
102    /// Reads a map from the deserializer.
103    ///
104    /// The map deserialization is driven by a consumer callback that is called
105    /// for each entry. The consumer receives the current state, the key, and the
106    /// deserializer, and returns the updated state.
107    ///
108    /// # Arguments
109    ///
110    /// * `schema` - The schema of the map being deserialized
111    /// * `state` - Initial state (typically a HashMap or collection)
112    /// * `consumer` - Callback invoked for each entry with (state, key, deserializer)
113    ///
114    /// # Returns
115    ///
116    /// The final state after processing all entries
117    fn read_map<T, F>(
118        &mut self,
119        schema: &dyn Schema,
120        state: T,
121        consumer: F,
122    ) -> Result<T, Self::Error>
123    where
124        F: FnMut(T, String, &mut Self) -> Result<T, Self::Error>;
125
126    /// Reads a boolean value.
127    fn read_boolean(&mut self, schema: &dyn Schema) -> Result<bool, Self::Error>;
128
129    /// Reads a byte (i8) value.
130    fn read_byte(&mut self, schema: &dyn Schema) -> Result<i8, Self::Error>;
131
132    /// Reads a short (i16) value.
133    fn read_short(&mut self, schema: &dyn Schema) -> Result<i16, Self::Error>;
134
135    /// Reads an integer (i32) value.
136    fn read_integer(&mut self, schema: &dyn Schema) -> Result<i32, Self::Error>;
137
138    /// Reads a long (i64) value.
139    fn read_long(&mut self, schema: &dyn Schema) -> Result<i64, Self::Error>;
140
141    /// Reads a float (f32) value.
142    fn read_float(&mut self, schema: &dyn Schema) -> Result<f32, Self::Error>;
143
144    /// Reads a double (f64) value.
145    fn read_double(&mut self, schema: &dyn Schema) -> Result<f64, Self::Error>;
146
147    /// Reads a big integer value.
148    fn read_big_integer(&mut self, schema: &dyn Schema) -> Result<BigInteger, Self::Error>;
149
150    /// Reads a big decimal value.
151    fn read_big_decimal(&mut self, schema: &dyn Schema) -> Result<BigDecimal, Self::Error>;
152
153    /// Reads a string value.
154    fn read_string(&mut self, schema: &dyn Schema) -> Result<String, Self::Error>;
155
156    /// Reads a blob (byte array) value.
157    fn read_blob(&mut self, schema: &dyn Schema) -> Result<Blob, Self::Error>;
158
159    /// Reads a timestamp value.
160    fn read_timestamp(&mut self, schema: &dyn Schema) -> Result<DateTime, Self::Error>;
161
162    /// Reads a document value.
163    fn read_document(&mut self, schema: &dyn Schema) -> Result<Document, Self::Error>;
164
165    /// Checks if the current value is null.
166    ///
167    /// This is used for sparse collections where null values are significant.
168    fn is_null(&self) -> bool;
169
170    /// Returns the size of the current container if known.
171    ///
172    /// This is an optimization hint that allows pre-allocating collections
173    /// with the correct capacity. Returns `None` if the size is unknown or
174    /// not applicable.
175    fn container_size(&self) -> Option<usize>;
176}