aws_smithy_json/
codec.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! JSON codec implementation for schema-based serialization.
7
8use aws_smithy_schema::codec::Codec;
9use aws_smithy_types::date_time::Format as TimestampFormat;
10
11mod deserializer;
12mod serializer;
13
14pub use deserializer::JsonDeserializer;
15pub use serializer::JsonSerializer;
16
17/// Configuration for JSON codec behavior.
18#[derive(Debug, Clone)]
19pub struct JsonCodecSettings {
20    /// Whether to use the @jsonName trait for member names.
21    pub use_json_name: bool,
22    /// Default timestamp format to use when not specified by @timestampFormat trait.
23    pub default_timestamp_format: TimestampFormat,
24    /// Whether to allow unknown union members during deserialization.
25    pub allow_unknown_union_members: bool,
26}
27
28impl Default for JsonCodecSettings {
29    fn default() -> Self {
30        Self {
31            use_json_name: true,
32            default_timestamp_format: TimestampFormat::EpochSeconds,
33            allow_unknown_union_members: false,
34        }
35    }
36}
37
38/// JSON codec for schema-based serialization and deserialization.
39///
40/// This codec implements the Smithy JSON protocol serialization rules,
41/// with configurable behavior for different protocol variants (e.g., AWS JSON RPC vs REST JSON).
42///
43/// # Examples
44///
45/// ```
46/// use aws_smithy_json::codec::{JsonCodec, JsonCodecSettings};
47/// use aws_smithy_schema::codec::Codec;
48/// use aws_smithy_types::date_time::Format;
49///
50/// // Create codec with default settings (REST JSON style)
51/// let codec = JsonCodec::new(JsonCodecSettings::default());
52///
53/// // Create codec for AWS JSON RPC (no jsonName, epoch-seconds timestamps)
54/// let codec = JsonCodec::new(JsonCodecSettings {
55///     use_json_name: false,
56///     default_timestamp_format: Format::EpochSeconds,
57///     allow_unknown_union_members: false,
58/// });
59///
60/// // Use the codec
61/// let _serializer = codec.create_serializer();
62/// let _deserializer = codec.create_deserializer(b"{}");
63/// ```
64#[derive(Debug, Clone)]
65pub struct JsonCodec {
66    settings: JsonCodecSettings,
67}
68
69impl JsonCodec {
70    /// Creates a new JSON codec with the given settings.
71    pub fn new(settings: JsonCodecSettings) -> Self {
72        Self { settings }
73    }
74
75    /// Returns the codec settings.
76    pub fn settings(&self) -> &JsonCodecSettings {
77        &self.settings
78    }
79}
80
81impl Default for JsonCodec {
82    fn default() -> Self {
83        Self::new(JsonCodecSettings::default())
84    }
85}
86
87impl Codec for JsonCodec {
88    type Serializer = JsonSerializer;
89    type Deserializer = JsonDeserializer;
90
91    fn create_serializer(&self) -> Self::Serializer {
92        JsonSerializer::new(self.settings.clone())
93    }
94
95    fn create_deserializer(&self, input: &[u8]) -> Self::Deserializer {
96        JsonDeserializer::new(input, self.settings.clone())
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_default_settings() {
106        let settings = JsonCodecSettings::default();
107        assert!(settings.use_json_name);
108        assert_eq!(
109            settings.default_timestamp_format,
110            TimestampFormat::EpochSeconds
111        );
112        assert!(!settings.allow_unknown_union_members);
113    }
114
115    #[test]
116    fn test_codec_creation() {
117        let codec = JsonCodec::default();
118        let _serializer = codec.create_serializer();
119        let _deserializer = codec.create_deserializer(b"{}");
120    }
121}