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