aws_smithy_schema/schema/
codec.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Codec trait for creating shape serializers and deserializers.
7//!
8//! A codec represents a specific serialization format (e.g., JSON, XML, CBOR)
9//! and provides methods to create serializers and deserializers for that format.
10
11pub mod http_string;
12
13use crate::serde::{ShapeDeserializer, ShapeSerializer};
14
15/// A codec for a specific serialization format.
16///
17/// Codecs are responsible for creating [`ShapeSerializer`] and [`ShapeDeserializer`]
18/// instances that can serialize and deserialize shapes to and from a specific format.
19///
20/// # Examples
21///
22/// Implementing a custom codec:
23///
24/// ```ignore
25/// use aws_smithy_schema::codec::Codec;
26/// use aws_smithy_schema::serde::{ShapeSerializer, ShapeDeserializer};
27///
28/// struct MyCodec {
29///     // codec configuration
30/// }
31///
32/// impl Codec for MyCodec {
33///     type Serializer = MySerializer;
34///     type Deserializer = MyDeserializer;
35///
36///     fn create_serializer(&self) -> Self::Serializer {
37///         MySerializer::new()
38///     }
39///
40///     fn create_deserializer(&self, input: &[u8]) -> Self::Deserializer {
41///         MyDeserializer::new(input)
42///     }
43/// }
44/// ```
45pub trait Codec {
46    /// The serializer type for this codec.
47    type Serializer: ShapeSerializer;
48
49    /// The deserializer type for this codec.
50    type Deserializer: ShapeDeserializer;
51
52    /// Creates a new serializer for this codec.
53    fn create_serializer(&self) -> Self::Serializer;
54
55    /// Creates a new deserializer for this codec from the given input bytes.
56    fn create_deserializer(&self, input: &[u8]) -> Self::Deserializer;
57}
58
59#[cfg(test)]
60mod test {
61    use super::*;
62    use crate::serde::{ShapeDeserializer, ShapeSerializer};
63    use crate::{prelude::*, Schema};
64    use std::fmt;
65
66    // Mock error type
67    #[derive(Debug)]
68    struct MockError;
69
70    impl fmt::Display for MockError {
71        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72            write!(f, "mock error")
73        }
74    }
75
76    impl std::error::Error for MockError {}
77
78    // Mock serializer
79    struct MockSerializer {
80        output: Vec<u8>,
81    }
82
83    impl ShapeSerializer for MockSerializer {
84        type Output = Vec<u8>;
85        type Error = MockError;
86
87        fn finish(self) -> Result<Self::Output, Self::Error> {
88            Ok(self.output)
89        }
90
91        fn write_struct<F>(
92            &mut self,
93            _schema: &dyn Schema,
94            _write_members: F,
95        ) -> Result<(), Self::Error>
96        where
97            F: FnOnce(&mut Self) -> Result<(), Self::Error>,
98        {
99            Ok(())
100        }
101
102        fn write_list<F>(
103            &mut self,
104            _schema: &dyn Schema,
105            _write_elements: F,
106        ) -> Result<(), Self::Error>
107        where
108            F: FnOnce(&mut Self) -> Result<(), Self::Error>,
109        {
110            Ok(())
111        }
112
113        fn write_map<F>(
114            &mut self,
115            _schema: &dyn Schema,
116            _write_entries: F,
117        ) -> Result<(), Self::Error>
118        where
119            F: FnOnce(&mut Self) -> Result<(), Self::Error>,
120        {
121            Ok(())
122        }
123
124        fn write_boolean(&mut self, _schema: &dyn Schema, _value: bool) -> Result<(), Self::Error> {
125            Ok(())
126        }
127
128        fn write_byte(&mut self, _schema: &dyn Schema, _value: i8) -> Result<(), Self::Error> {
129            Ok(())
130        }
131
132        fn write_short(&mut self, _schema: &dyn Schema, _value: i16) -> Result<(), Self::Error> {
133            Ok(())
134        }
135
136        fn write_integer(&mut self, _schema: &dyn Schema, _value: i32) -> Result<(), Self::Error> {
137            Ok(())
138        }
139
140        fn write_long(&mut self, _schema: &dyn Schema, _value: i64) -> Result<(), Self::Error> {
141            Ok(())
142        }
143
144        fn write_float(&mut self, _schema: &dyn Schema, _value: f32) -> Result<(), Self::Error> {
145            Ok(())
146        }
147
148        fn write_double(&mut self, _schema: &dyn Schema, _value: f64) -> Result<(), Self::Error> {
149            Ok(())
150        }
151
152        fn write_big_integer(
153            &mut self,
154            _schema: &dyn Schema,
155            _value: &aws_smithy_types::BigInteger,
156        ) -> Result<(), Self::Error> {
157            Ok(())
158        }
159
160        fn write_big_decimal(
161            &mut self,
162            _schema: &dyn Schema,
163            _value: &aws_smithy_types::BigDecimal,
164        ) -> Result<(), Self::Error> {
165            Ok(())
166        }
167
168        fn write_string(&mut self, _schema: &dyn Schema, _value: &str) -> Result<(), Self::Error> {
169            Ok(())
170        }
171
172        fn write_blob(
173            &mut self,
174            _schema: &dyn Schema,
175            _value: &aws_smithy_types::Blob,
176        ) -> Result<(), Self::Error> {
177            Ok(())
178        }
179
180        fn write_timestamp(
181            &mut self,
182            _schema: &dyn Schema,
183            _value: &aws_smithy_types::DateTime,
184        ) -> Result<(), Self::Error> {
185            Ok(())
186        }
187
188        fn write_document(
189            &mut self,
190            _schema: &dyn Schema,
191            _value: &aws_smithy_types::Document,
192        ) -> Result<(), Self::Error> {
193            Ok(())
194        }
195
196        fn write_null(&mut self, _schema: &dyn Schema) -> Result<(), Self::Error> {
197            Ok(())
198        }
199    }
200
201    // Mock deserializer
202    struct MockDeserializer {
203        #[allow(dead_code)]
204        input: Vec<u8>,
205    }
206
207    impl ShapeDeserializer for MockDeserializer {
208        type Error = MockError;
209
210        fn read_struct<T, F>(
211            &mut self,
212            _schema: &dyn Schema,
213            state: T,
214            _consumer: F,
215        ) -> Result<T, Self::Error>
216        where
217            F: FnMut(T, &dyn Schema, &mut Self) -> Result<T, Self::Error>,
218        {
219            Ok(state)
220        }
221
222        fn read_list<T, F>(
223            &mut self,
224            _schema: &dyn Schema,
225            state: T,
226            _consumer: F,
227        ) -> Result<T, Self::Error>
228        where
229            F: FnMut(T, &mut Self) -> Result<T, Self::Error>,
230        {
231            Ok(state)
232        }
233
234        fn read_map<T, F>(
235            &mut self,
236            _schema: &dyn Schema,
237            state: T,
238            _consumer: F,
239        ) -> Result<T, Self::Error>
240        where
241            F: FnMut(T, String, &mut Self) -> Result<T, Self::Error>,
242        {
243            Ok(state)
244        }
245
246        fn read_boolean(&mut self, _schema: &dyn Schema) -> Result<bool, Self::Error> {
247            Ok(false)
248        }
249
250        fn read_byte(&mut self, _schema: &dyn Schema) -> Result<i8, Self::Error> {
251            Ok(0)
252        }
253
254        fn read_short(&mut self, _schema: &dyn Schema) -> Result<i16, Self::Error> {
255            Ok(0)
256        }
257
258        fn read_integer(&mut self, _schema: &dyn Schema) -> Result<i32, Self::Error> {
259            Ok(0)
260        }
261
262        fn read_long(&mut self, _schema: &dyn Schema) -> Result<i64, Self::Error> {
263            Ok(0)
264        }
265
266        fn read_float(&mut self, _schema: &dyn Schema) -> Result<f32, Self::Error> {
267            Ok(0.0)
268        }
269
270        fn read_double(&mut self, _schema: &dyn Schema) -> Result<f64, Self::Error> {
271            Ok(0.0)
272        }
273
274        fn read_big_integer(
275            &mut self,
276            _schema: &dyn Schema,
277        ) -> Result<aws_smithy_types::BigInteger, Self::Error> {
278            use std::str::FromStr;
279            Ok(aws_smithy_types::BigInteger::from_str("0").unwrap())
280        }
281
282        fn read_big_decimal(
283            &mut self,
284            _schema: &dyn Schema,
285        ) -> Result<aws_smithy_types::BigDecimal, Self::Error> {
286            use std::str::FromStr;
287            Ok(aws_smithy_types::BigDecimal::from_str("0").unwrap())
288        }
289
290        fn read_string(&mut self, _schema: &dyn Schema) -> Result<String, Self::Error> {
291            Ok(String::new())
292        }
293
294        fn read_blob(
295            &mut self,
296            _schema: &dyn Schema,
297        ) -> Result<aws_smithy_types::Blob, Self::Error> {
298            Ok(aws_smithy_types::Blob::new(Vec::new()))
299        }
300
301        fn read_timestamp(
302            &mut self,
303            _schema: &dyn Schema,
304        ) -> Result<aws_smithy_types::DateTime, Self::Error> {
305            Ok(aws_smithy_types::DateTime::from_secs(0))
306        }
307
308        fn read_document(
309            &mut self,
310            _schema: &dyn Schema,
311        ) -> Result<aws_smithy_types::Document, Self::Error> {
312            Ok(aws_smithy_types::Document::Null)
313        }
314
315        fn is_null(&self) -> bool {
316            false
317        }
318
319        fn container_size(&self) -> Option<usize> {
320            None
321        }
322    }
323
324    // Mock codec
325    struct MockCodec;
326
327    impl Codec for MockCodec {
328        type Serializer = MockSerializer;
329        type Deserializer = MockDeserializer;
330
331        fn create_serializer(&self) -> Self::Serializer {
332            MockSerializer { output: Vec::new() }
333        }
334
335        fn create_deserializer(&self, input: &[u8]) -> Self::Deserializer {
336            MockDeserializer {
337                input: input.to_vec(),
338            }
339        }
340    }
341
342    #[test]
343    fn test_codec_create_serializer() {
344        let codec = MockCodec;
345        let mut serializer = codec.create_serializer();
346
347        // Test that we can use the serializer
348        serializer.write_string(&STRING, "test").unwrap();
349        let output = serializer.finish().unwrap();
350        assert_eq!(output, Vec::<u8>::new());
351    }
352
353    #[test]
354    fn test_codec_create_deserializer() {
355        let codec = MockCodec;
356        let input = b"test data";
357        let mut deserializer = codec.create_deserializer(input);
358
359        // Test that we can use the deserializer
360        let result = deserializer.read_string(&STRING).unwrap();
361        assert_eq!(result, "");
362    }
363
364    #[test]
365    fn test_codec_roundtrip() {
366        let codec = MockCodec;
367
368        // Serialize
369        let mut serializer = codec.create_serializer();
370        serializer.write_integer(&INTEGER, 42).unwrap();
371        let bytes = serializer.finish().unwrap();
372
373        // Deserialize
374        let mut deserializer = codec.create_deserializer(&bytes);
375        let value = deserializer.read_integer(&INTEGER).unwrap();
376        assert_eq!(value, 0); // Mock deserializer always returns 0
377    }
378}