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 + | }
|