AWS SDK

AWS SDK

rev. 17f487400210899258c016324cc68c1c68558fab (ignoring whitespace)

Files changed:

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-json/Cargo.toml

@@ -1,1 +22,26 @@
    6      6   
description = "Token streaming JSON parser for smithy-rs."
    7      7   
edition = "2021"
    8      8   
license = "Apache-2.0"
    9      9   
repository = "https://github.com/smithy-lang/smithy-rs"
   10     10   
rust-version = "1.91.1"
   11     11   
[package.metadata.docs.rs]
   12     12   
all-features = true
   13     13   
targets = ["x86_64-unknown-linux-gnu"]
   14     14   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   15     15   
rustdoc-args = ["--cfg", "docsrs"]
          16  +
[dependencies.aws-smithy-schema]
          17  +
path = "../aws-smithy-schema"
          18  +
version = "0.1.0"
          19  +
   16     20   
[dependencies.aws-smithy-types]
   17     21   
path = "../aws-smithy-types"
   18     22   
version = "1.4.6"
   19     23   
   20     24   
[dev-dependencies]
   21     25   
proptest = "1"
   22     26   
serde_json = "1.0"

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-json/external-types.toml

@@ -1,1 +3,4 @@
    1      1   
allowed_external_types = [
    2      2   
    "aws_smithy_types::*",
           3  +
    "aws_smithy_schema::*",
    3      4   
]

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-json/src/codec.rs

@@ -0,1 +0,121 @@
           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  +
           8  +
use aws_smithy_schema::codec::Codec;
           9  +
use aws_smithy_types::date_time::Format as TimestampFormat;
          10  +
          11  +
mod deserializer;
          12  +
mod serializer;
          13  +
          14  +
pub use deserializer::JsonDeserializer;
          15  +
pub use serializer::JsonSerializer;
          16  +
          17  +
/// Configuration for JSON codec behavior.
          18  +
#[derive(Debug, Clone)]
          19  +
pub 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  +
          28  +
impl 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)]
          65  +
pub struct JsonCodec {
          66  +
    settings: JsonCodecSettings,
          67  +
}
          68  +
          69  +
impl 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  +
          81  +
impl Default for JsonCodec {
          82  +
    fn default() -> Self {
          83  +
        Self::new(JsonCodecSettings::default())
          84  +
    }
          85  +
}
          86  +
          87  +
impl Codec for JsonCodec {
          88  +
    type Serializer = JsonSerializer;
          89  +
    type Deserializer<'a> = JsonDeserializer<'a>;
          90  +
          91  +
    fn create_serializer(&self) -> Self::Serializer {
          92  +
        JsonSerializer::new(self.settings.clone())
          93  +
    }
          94  +
          95  +
    fn create_deserializer<'a>(&self, input: &'a [u8]) -> Self::Deserializer<'a> {
          96  +
        JsonDeserializer::new(input, self.settings.clone())
          97  +
    }
          98  +
}
          99  +
         100  +
#[cfg(test)]
         101  +
mod 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  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-json/src/codec/deserializer.rs

@@ -0,1 +0,1182 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! JSON deserializer implementation.
           7  +
           8  +
use aws_smithy_schema::serde::ShapeDeserializer;
           9  +
use aws_smithy_schema::Schema;
          10  +
use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime, Document, Number};
          11  +
use std::fmt;
          12  +
          13  +
use crate::codec::JsonCodecSettings;
          14  +
use crate::deserialize::{json_token_iter, Token};
          15  +
          16  +
/// Error type for JSON deserialization.
          17  +
#[derive(Debug)]
          18  +
pub enum JsonDeserializerError {
          19  +
    /// An error occurred during JSON parsing.
          20  +
    ParseError(String),
          21  +
}
          22  +
          23  +
impl fmt::Display for JsonDeserializerError {
          24  +
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
          25  +
        match self {
          26  +
            Self::ParseError(msg) => write!(f, "JSON parse error: {}", msg),
          27  +
        }
          28  +
    }
          29  +
}
          30  +
          31  +
impl std::error::Error for JsonDeserializerError {}
          32  +
          33  +
/// JSON deserializer that implements the ShapeDeserializer trait.
          34  +
pub struct JsonDeserializer<'a> {
          35  +
    input: &'a [u8],
          36  +
    position: usize,
          37  +
    // TODO(schema): Need to figure out how this will work with traits like
          38  +
    // jsonName. Will figure that out once I am codegening real Schemas
          39  +
    _settings: JsonCodecSettings,
          40  +
}
          41  +
          42  +
impl<'a> JsonDeserializer<'a> {
          43  +
    /// Creates a new JSON deserializer with the given settings.
          44  +
    pub fn new(input: &'a [u8], settings: JsonCodecSettings) -> Self {
          45  +
        Self {
          46  +
            input,
          47  +
            position: 0,
          48  +
            _settings: settings,
          49  +
        }
          50  +
    }
          51  +
          52  +
    fn remaining(&self) -> &[u8] {
          53  +
        &self.input[self.position..]
          54  +
    }
          55  +
          56  +
    fn advance_by(&mut self, n: usize) {
          57  +
        self.position += n;
          58  +
    }
          59  +
}
          60  +
          61  +
impl<'a> ShapeDeserializer for JsonDeserializer<'a> {
          62  +
    type Error = JsonDeserializerError;
          63  +
          64  +
    fn read_struct<T, F>(
          65  +
        &mut self,
          66  +
        schema: &dyn Schema,
          67  +
        mut state: T,
          68  +
        mut consumer: F,
          69  +
    ) -> Result<T, Self::Error>
          70  +
    where
          71  +
        F: FnMut(T, &dyn Schema, &mut Self) -> Result<T, Self::Error>,
          72  +
    {
          73  +
        // Expect opening brace
          74  +
        self.skip_whitespace();
          75  +
        if self.remaining().first() != Some(&b'{') {
          76  +
            return Err(JsonDeserializerError::ParseError("Expected object".into()));
          77  +
        }
          78  +
        self.advance_by(1);
          79  +
          80  +
        loop {
          81  +
            self.skip_whitespace();
          82  +
          83  +
            // Check for end of object
          84  +
            if self.remaining().first() == Some(&b'}') {
          85  +
                self.advance_by(1);
          86  +
                break;
          87  +
            }
          88  +
          89  +
            // Expect a key (quoted string)
          90  +
            if self.remaining().first() != Some(&b'"') {
          91  +
                return Err(JsonDeserializerError::ParseError(
          92  +
                    "Expected object key".into(),
          93  +
                ));
          94  +
            }
          95  +
          96  +
            // Parse the key using the token iterator
          97  +
            let mut iter = json_token_iter(self.remaining());
          98  +
            let key_str = match iter.next() {
          99  +
                Some(Ok(Token::ValueString { value, .. })) => {
         100  +
                    let key_len = value.as_escaped_str().len();
         101  +
                    let key = value
         102  +
                        .to_unescaped()
         103  +
                        .map_err(|e| JsonDeserializerError::ParseError(e.to_string()))?
         104  +
                        .into_owned();
         105  +
                    // Advance past opening quote + key + closing quote
         106  +
                    self.advance_by(key_len + 2);
         107  +
                    key
         108  +
                }
         109  +
                _ => {
         110  +
                    return Err(JsonDeserializerError::ParseError(
         111  +
                        "Expected object key".into(),
         112  +
                    ))
         113  +
                }
         114  +
            };
         115  +
         116  +
            // Skip whitespace and expect colon
         117  +
            self.skip_whitespace();
         118  +
            if self.remaining().first() != Some(&b':') {
         119  +
                return Err(JsonDeserializerError::ParseError(
         120  +
                    "Expected colon after key".into(),
         121  +
                ));
         122  +
            }
         123  +
            self.advance_by(1);
         124  +
            self.skip_whitespace();
         125  +
         126  +
            // Process the value
         127  +
            if let Some(member_schema) = schema.member_schema(&key_str) {
         128  +
                state = consumer(state, member_schema, self)?;
         129  +
            } else {
         130  +
                self.skip_value()?;
         131  +
            }
         132  +
        }
         133  +
         134  +
        Ok(state)
         135  +
    }
         136  +
         137  +
    fn read_list<T, F>(
         138  +
        &mut self,
         139  +
        _schema: &dyn Schema,
         140  +
        mut state: T,
         141  +
        mut consumer: F,
         142  +
    ) -> Result<T, Self::Error>
         143  +
    where
         144  +
        F: FnMut(T, &mut Self) -> Result<T, Self::Error>,
         145  +
    {
         146  +
        self.skip_whitespace();
         147  +
        if self.remaining().first() != Some(&b'[') {
         148  +
            return Err(JsonDeserializerError::ParseError("Expected array".into()));
         149  +
        }
         150  +
        self.advance_by(1);
         151  +
         152  +
        loop {
         153  +
            self.skip_whitespace();
         154  +
            if self.remaining().first() == Some(&b']') {
         155  +
                self.advance_by(1);
         156  +
                break;
         157  +
            }
         158  +
            state = consumer(state, self)?;
         159  +
        }
         160  +
         161  +
        Ok(state)
         162  +
    }
         163  +
         164  +
    fn read_map<T, F>(
         165  +
        &mut self,
         166  +
        _schema: &dyn Schema,
         167  +
        mut state: T,
         168  +
        mut consumer: F,
         169  +
    ) -> Result<T, Self::Error>
         170  +
    where
         171  +
        F: FnMut(T, String, &mut Self) -> Result<T, Self::Error>,
         172  +
    {
         173  +
        self.skip_whitespace();
         174  +
        if self.remaining().first() != Some(&b'{') {
         175  +
            return Err(JsonDeserializerError::ParseError("Expected object".into()));
         176  +
        }
         177  +
        self.advance_by(1);
         178  +
         179  +
        loop {
         180  +
            self.skip_whitespace();
         181  +
            if self.remaining().first() == Some(&b'}') {
         182  +
                self.advance_by(1);
         183  +
                break;
         184  +
            }
         185  +
         186  +
            if self.remaining().first() != Some(&b'"') {
         187  +
                return Err(JsonDeserializerError::ParseError("Expected key".into()));
         188  +
            }
         189  +
         190  +
            let mut iter = json_token_iter(self.remaining());
         191  +
            let key = match iter.next() {
         192  +
                Some(Ok(Token::ValueString { value, .. })) => {
         193  +
                    let len = value.as_escaped_str().len();
         194  +
                    let key = value
         195  +
                        .to_unescaped()
         196  +
                        .map_err(|e| JsonDeserializerError::ParseError(e.to_string()))?
         197  +
                        .into_owned();
         198  +
                    self.advance_by(len + 2);
         199  +
                    key
         200  +
                }
         201  +
                _ => return Err(JsonDeserializerError::ParseError("Expected key".into())),
         202  +
            };
         203  +
         204  +
            self.skip_whitespace();
         205  +
            if self.remaining().first() != Some(&b':') {
         206  +
                return Err(JsonDeserializerError::ParseError("Expected colon".into()));
         207  +
            }
         208  +
            self.advance_by(1);
         209  +
            self.skip_whitespace();
         210  +
         211  +
            state = consumer(state, key, self)?;
         212  +
        }
         213  +
         214  +
        Ok(state)
         215  +
    }
         216  +
         217  +
    fn read_boolean(&mut self, _schema: &dyn Schema) -> Result<bool, Self::Error> {
         218  +
        let mut iter = json_token_iter(self.remaining());
         219  +
        match iter.next() {
         220  +
            Some(Ok(Token::ValueBool { value, .. })) => {
         221  +
                self.advance_by(if value { 4 } else { 5 });
         222  +
                Ok(value)
         223  +
            }
         224  +
            _ => Err(JsonDeserializerError::ParseError("Expected boolean".into())),
         225  +
        }
         226  +
    }
         227  +
         228  +
    fn read_byte(&mut self, _schema: &dyn Schema) -> Result<i8, Self::Error> {
         229  +
        self.read_integer_value().and_then(|n| {
         230  +
            i8::try_from(n).map_err(|_| {
         231  +
                JsonDeserializerError::ParseError("Value out of range for byte".into())
         232  +
            })
         233  +
        })
         234  +
    }
         235  +
         236  +
    fn read_short(&mut self, _schema: &dyn Schema) -> Result<i16, Self::Error> {
         237  +
        self.read_integer_value().and_then(|n| {
         238  +
            i16::try_from(n).map_err(|_| {
         239  +
                JsonDeserializerError::ParseError("Value out of range for short".into())
         240  +
            })
         241  +
        })
         242  +
    }
         243  +
         244  +
    fn read_integer(&mut self, _schema: &dyn Schema) -> Result<i32, Self::Error> {
         245  +
        self.read_integer_value().and_then(|n| {
         246  +
            i32::try_from(n).map_err(|_| {
         247  +
                JsonDeserializerError::ParseError("Value out of range for integer".into())
         248  +
            })
         249  +
        })
         250  +
    }
         251  +
         252  +
    fn read_long(&mut self, _schema: &dyn Schema) -> Result<i64, Self::Error> {
         253  +
        self.read_integer_value()
         254  +
    }
         255  +
         256  +
    fn read_float(&mut self, _schema: &dyn Schema) -> Result<f32, Self::Error> {
         257  +
        self.read_float_value().map(|f| f as f32)
         258  +
    }
         259  +
         260  +
    fn read_double(&mut self, _schema: &dyn Schema) -> Result<f64, Self::Error> {
         261  +
        self.read_float_value()
         262  +
    }
         263  +
         264  +
    fn read_big_integer(&mut self, _schema: &dyn Schema) -> Result<BigInteger, Self::Error> {
         265  +
        use std::str::FromStr;
         266  +
        let mut iter = json_token_iter(self.remaining());
         267  +
        match iter.next() {
         268  +
            Some(Ok(Token::ValueNumber { .. })) => {
         269  +
                self.consume_number();
         270  +
                BigInteger::from_str("0")
         271  +
                    .map_err(|e| JsonDeserializerError::ParseError(e.to_string()))
         272  +
            }
         273  +
            _ => Err(JsonDeserializerError::ParseError("Expected number".into())),
         274  +
        }
         275  +
    }
         276  +
         277  +
    fn read_big_decimal(&mut self, _schema: &dyn Schema) -> Result<BigDecimal, Self::Error> {
         278  +
        use std::str::FromStr;
         279  +
        let mut iter = json_token_iter(self.remaining());
         280  +
        match iter.next() {
         281  +
            Some(Ok(Token::ValueNumber { .. })) => {
         282  +
                self.consume_number();
         283  +
                BigDecimal::from_str("0")
         284  +
                    .map_err(|e| JsonDeserializerError::ParseError(e.to_string()))
         285  +
            }
         286  +
            _ => Err(JsonDeserializerError::ParseError("Expected number".into())),
         287  +
        }
         288  +
    }
         289  +
         290  +
    fn read_string(&mut self, _schema: &dyn Schema) -> Result<String, Self::Error> {
         291  +
        let mut iter = json_token_iter(self.remaining());
         292  +
        match iter.next() {
         293  +
            Some(Ok(Token::ValueString { value, .. })) => {
         294  +
                let len = value.as_escaped_str().len();
         295  +
                let result = value
         296  +
                    .to_unescaped()
         297  +
                    .map(|s| s.into_owned())
         298  +
                    .map_err(|e| JsonDeserializerError::ParseError(e.to_string()))?;
         299  +
                self.advance_by(len + 2);
         300  +
                Ok(result)
         301  +
            }
         302  +
            _ => Err(JsonDeserializerError::ParseError("Expected string".into())),
         303  +
        }
         304  +
    }
         305  +
         306  +
    fn read_blob(&mut self, _schema: &dyn Schema) -> Result<Blob, Self::Error> {
         307  +
        let s = self.read_string(_schema)?;
         308  +
        Ok(Blob::new(s.into_bytes()))
         309  +
    }
         310  +
         311  +
    fn read_timestamp(&mut self, _schema: &dyn Schema) -> Result<DateTime, Self::Error> {
         312  +
        let mut iter = json_token_iter(self.remaining());
         313  +
        match iter.next() {
         314  +
            Some(Ok(Token::ValueNumber {
         315  +
                value: Number::PosInt(n),
         316  +
                ..
         317  +
            })) => {
         318  +
                self.consume_number();
         319  +
                Ok(DateTime::from_secs(n as i64))
         320  +
            }
         321  +
            Some(Ok(Token::ValueNumber {
         322  +
                value: Number::NegInt(n),
         323  +
                ..
         324  +
            })) => {
         325  +
                self.consume_number();
         326  +
                Ok(DateTime::from_secs(n))
         327  +
            }
         328  +
            _ => Err(JsonDeserializerError::ParseError(
         329  +
                "Expected timestamp".into(),
         330  +
            )),
         331  +
        }
         332  +
    }
         333  +
         334  +
    fn read_document(&mut self, _schema: &dyn Schema) -> Result<Document, Self::Error> {
         335  +
        let mut iter = json_token_iter(self.remaining());
         336  +
        match iter.next() {
         337  +
            Some(Ok(Token::ValueNull { .. })) => {
         338  +
                self.advance_by(4);
         339  +
                Ok(Document::Null)
         340  +
            }
         341  +
            _ => Err(JsonDeserializerError::ParseError(
         342  +
                "Document deserialization not fully implemented".into(),
         343  +
            )),
         344  +
        }
         345  +
    }
         346  +
         347  +
    fn is_null(&self) -> bool {
         348  +
        let mut iter = json_token_iter(self.remaining());
         349  +
        matches!(iter.next(), Some(Ok(Token::ValueNull { .. })))
         350  +
    }
         351  +
         352  +
    fn container_size(&self) -> Option<usize> {
         353  +
        let mut iter = json_token_iter(self.remaining());
         354  +
        match iter.next()? {
         355  +
            Ok(Token::StartArray { .. }) => {
         356  +
                let mut count = 0;
         357  +
                let mut depth = 1;
         358  +
                for token in iter {
         359  +
                    match token {
         360  +
                        Ok(Token::StartArray { .. }) | Ok(Token::StartObject { .. }) => {
         361  +
                            if depth == 1 {
         362  +
                                count += 1;
         363  +
                            }
         364  +
                            depth += 1;
         365  +
                        }
         366  +
                        Ok(Token::EndArray { .. }) | Ok(Token::EndObject { .. }) => {
         367  +
                            depth -= 1;
         368  +
                            if depth == 0 {
         369  +
                                return Some(count);
         370  +
                            }
         371  +
                        }
         372  +
                        Ok(Token::ValueBool { .. })
         373  +
                        | Ok(Token::ValueNull { .. })
         374  +
                        | Ok(Token::ValueString { .. })
         375  +
                        | Ok(Token::ValueNumber { .. })
         376  +
                            if depth == 1 =>
         377  +
                        {
         378  +
                            count += 1
         379  +
                        }
         380  +
                        _ => {}
         381  +
                    }
         382  +
                }
         383  +
                None
         384  +
            }
         385  +
            Ok(Token::StartObject { .. }) => {
         386  +
                let mut count = 0;
         387  +
                let mut depth = 1;
         388  +
                for token in iter {
         389  +
                    match token {
         390  +
                        Ok(Token::StartArray { .. }) | Ok(Token::StartObject { .. }) => depth += 1,
         391  +
                        Ok(Token::EndArray { .. }) | Ok(Token::EndObject { .. }) => {
         392  +
                            depth -= 1;
         393  +
                            if depth == 0 {
         394  +
                                return Some(count);
         395  +
                            }
         396  +
                        }
         397  +
                        Ok(Token::ObjectKey { .. }) if depth == 1 => count += 1,
         398  +
                        _ => {}
         399  +
                    }
         400  +
                }
         401  +
                None
         402  +
            }
         403  +
            _ => None,
         404  +
        }
         405  +
    }
         406  +
}
         407  +
         408  +
impl<'a> JsonDeserializer<'a> {
         409  +
    fn skip_whitespace(&mut self) {
         410  +
        while self.position < self.input.len() {
         411  +
            match self.input[self.position] {
         412  +
                b' ' | b'\t' | b'\n' | b'\r' | b',' => self.position += 1,
         413  +
                _ => break,
         414  +
            }
         415  +
        }
         416  +
    }
         417  +
         418  +
    fn consume_number(&mut self) {
         419  +
        let mut len = 0;
         420  +
        for &b in self.remaining() {
         421  +
            if b.is_ascii_digit() || b == b'-' || b == b'.' || b == b'e' || b == b'E' || b == b'+' {
         422  +
                len += 1;
         423  +
            } else {
         424  +
                break;
         425  +
            }
         426  +
        }
         427  +
        self.advance_by(len);
         428  +
    }
         429  +
         430  +
    fn skip_value(&mut self) -> Result<(), JsonDeserializerError> {
         431  +
        let mut depth = 0;
         432  +
        loop {
         433  +
            let mut iter = json_token_iter(self.remaining());
         434  +
            match iter.next() {
         435  +
                Some(Ok(Token::StartObject { .. })) | Some(Ok(Token::StartArray { .. })) => {
         436  +
                    self.advance_by(1);
         437  +
                    depth += 1;
         438  +
                }
         439  +
                Some(Ok(Token::EndObject { .. })) | Some(Ok(Token::EndArray { .. })) => {
         440  +
                    self.advance_by(1);
         441  +
                    if depth == 0 {
         442  +
                        return Err(JsonDeserializerError::ParseError(
         443  +
                            "Unexpected end token".into(),
         444  +
                        ));
         445  +
                    }
         446  +
                    depth -= 1;
         447  +
                    if depth == 0 {
         448  +
                        return Ok(());
         449  +
                    }
         450  +
                }
         451  +
                Some(Ok(Token::ValueBool { value, .. })) if depth == 0 => {
         452  +
                    self.advance_by(if value { 4 } else { 5 });
         453  +
                    return Ok(());
         454  +
                }
         455  +
                Some(Ok(Token::ValueNull { .. })) if depth == 0 => {
         456  +
                    self.advance_by(4);
         457  +
                    return Ok(());
         458  +
                }
         459  +
                Some(Ok(Token::ValueString { value, .. })) if depth == 0 => {
         460  +
                    self.advance_by(value.as_escaped_str().len() + 2);
         461  +
                    return Ok(());
         462  +
                }
         463  +
                Some(Ok(Token::ValueNumber { .. })) if depth == 0 => {
         464  +
                    self.consume_number();
         465  +
                    return Ok(());
         466  +
                }
         467  +
                Some(Ok(Token::ObjectKey { key, .. })) => {
         468  +
                    self.advance_by(key.as_escaped_str().len() + 3);
         469  +
                }
         470  +
                Some(Ok(_)) => {}
         471  +
                Some(Err(e)) => return Err(JsonDeserializerError::ParseError(e.to_string())),
         472  +
                None => {
         473  +
                    return Err(JsonDeserializerError::ParseError(
         474  +
                        "Unexpected end of input".into(),
         475  +
                    ))
         476  +
                }
         477  +
            }
         478  +
        }
         479  +
    }
         480  +
         481  +
    fn read_integer_value(&mut self) -> Result<i64, JsonDeserializerError> {
         482  +
        let mut iter = json_token_iter(self.remaining());
         483  +
        match iter.next() {
         484  +
            Some(Ok(Token::ValueNumber {
         485  +
                value: Number::PosInt(n),
         486  +
                ..
         487  +
            })) => {
         488  +
                self.consume_number();
         489  +
                i64::try_from(n)
         490  +
                    .map_err(|_| JsonDeserializerError::ParseError("Value out of range".into()))
         491  +
            }
         492  +
            Some(Ok(Token::ValueNumber {
         493  +
                value: Number::NegInt(n),
         494  +
                ..
         495  +
            })) => {
         496  +
                self.consume_number();
         497  +
                Ok(n)
         498  +
            }
         499  +
            _ => Err(JsonDeserializerError::ParseError("Expected integer".into())),
         500  +
        }
         501  +
    }
         502  +
         503  +
    fn read_float_value(&mut self) -> Result<f64, JsonDeserializerError> {
         504  +
        let mut iter = json_token_iter(self.remaining());
         505  +
        match iter.next() {
         506  +
            Some(Ok(Token::ValueNumber {
         507  +
                value: Number::Float(f),
         508  +
                ..
         509  +
            })) => {
         510  +
                self.consume_number();
         511  +
                Ok(f)
         512  +
            }
         513  +
            Some(Ok(Token::ValueNumber {
         514  +
                value: Number::PosInt(n),
         515  +
                ..
         516  +
            })) => {
         517  +
                self.consume_number();
         518  +
                Ok(n as f64)
         519  +
            }
         520  +
            Some(Ok(Token::ValueNumber {
         521  +
                value: Number::NegInt(n),
         522  +
                ..
         523  +
            })) => {
         524  +
                self.consume_number();
         525  +
                Ok(n as f64)
         526  +
            }
         527  +
            _ => Err(JsonDeserializerError::ParseError("Expected number".into())),
         528  +
        }
         529  +
    }
         530  +
}
         531  +
         532  +
#[cfg(test)]
         533  +
mod tests {
         534  +
    use super::*;
         535  +
         536  +
    fn dummy_schema() -> &'static impl aws_smithy_schema::Schema {
         537  +
        &aws_smithy_schema::prelude::STRING
         538  +
    }
         539  +
         540  +
    #[test]
         541  +
    fn test_read_boolean() {
         542  +
        let mut deser = JsonDeserializer::new(b"true", JsonCodecSettings::default());
         543  +
        assert_eq!(deser.read_boolean(dummy_schema()).unwrap(), true);
         544  +
         545  +
        let mut deser = JsonDeserializer::new(b"false", JsonCodecSettings::default());
         546  +
        assert_eq!(deser.read_boolean(dummy_schema()).unwrap(), false);
         547  +
    }
         548  +
         549  +
    #[test]
         550  +
    fn test_read_integer() {
         551  +
        let mut deser = JsonDeserializer::new(b"42", JsonCodecSettings::default());
         552  +
        assert_eq!(deser.read_integer(dummy_schema()).unwrap(), 42);
         553  +
         554  +
        let mut deser = JsonDeserializer::new(b"-123", JsonCodecSettings::default());
         555  +
        assert_eq!(deser.read_integer(dummy_schema()).unwrap(), -123);
         556  +
    }
         557  +
         558  +
    #[test]
         559  +
    fn test_read_long() {
         560  +
        let mut deser = JsonDeserializer::new(b"9223372036854775807", JsonCodecSettings::default());
         561  +
        assert_eq!(deser.read_long(dummy_schema()).unwrap(), i64::MAX);
         562  +
    }
         563  +
         564  +
    #[test]
         565  +
    fn test_read_float() {
         566  +
        let mut deser = JsonDeserializer::new(b"3.14", JsonCodecSettings::default());
         567  +
        assert!((deser.read_float(dummy_schema()).unwrap() - 3.14).abs() < 0.01);
         568  +
    }
         569  +
         570  +
    #[test]
         571  +
    fn test_read_double() {
         572  +
        let mut deser = JsonDeserializer::new(b"2.718", JsonCodecSettings::default());
         573  +
        assert!((deser.read_double(dummy_schema()).unwrap() - 2.718).abs() < 0.001);
         574  +
    }
         575  +
         576  +
    #[test]
         577  +
    fn test_read_string() {
         578  +
        let mut deser = JsonDeserializer::new(br#""hello world""#, JsonCodecSettings::default());
         579  +
        assert_eq!(deser.read_string(dummy_schema()).unwrap(), "hello world");
         580  +
         581  +
        let mut deser = JsonDeserializer::new(br#""hello\nworld""#, JsonCodecSettings::default());
         582  +
        assert_eq!(deser.read_string(dummy_schema()).unwrap(), "hello\nworld");
         583  +
    }
         584  +
         585  +
    #[test]
         586  +
    fn test_is_null() {
         587  +
        let deser = JsonDeserializer::new(b"null", JsonCodecSettings::default());
         588  +
        assert!(deser.is_null());
         589  +
         590  +
        let deser = JsonDeserializer::new(b"42", JsonCodecSettings::default());
         591  +
        assert!(!deser.is_null());
         592  +
    }
         593  +
         594  +
    #[test]
         595  +
    fn test_read_byte_range() {
         596  +
        let mut deser = JsonDeserializer::new(b"127", JsonCodecSettings::default());
         597  +
        assert_eq!(deser.read_byte(dummy_schema()).unwrap(), 127);
         598  +
         599  +
        let mut deser = JsonDeserializer::new(b"128", JsonCodecSettings::default());
         600  +
        assert!(deser.read_byte(dummy_schema()).is_err());
         601  +
    }
         602  +
         603  +
    #[test]
         604  +
    fn test_read_struct() {
         605  +
        use aws_smithy_schema::{prelude, Schema, ShapeId, ShapeType, TraitMap};
         606  +
         607  +
        #[derive(Debug, Default, PartialEq)]
         608  +
        struct Person {
         609  +
            first_name: String,
         610  +
            last_name: String,
         611  +
            age: i32,
         612  +
        }
         613  +
         614  +
        struct MemberSchema {
         615  +
            name: &'static str,
         616  +
            target: &'static dyn Schema,
         617  +
        }
         618  +
         619  +
        impl Schema for MemberSchema {
         620  +
            fn shape_id(&self) -> &ShapeId {
         621  +
                self.target.shape_id()
         622  +
            }
         623  +
            fn shape_type(&self) -> ShapeType {
         624  +
                self.target.shape_type()
         625  +
            }
         626  +
            fn traits(&self) -> &TraitMap {
         627  +
                self.target.traits()
         628  +
            }
         629  +
            fn member_name(&self) -> Option<&str> {
         630  +
                Some(self.name)
         631  +
            }
         632  +
        }
         633  +
         634  +
        static FIRST_NAME: MemberSchema = MemberSchema {
         635  +
            name: "firstName",
         636  +
            target: &prelude::STRING,
         637  +
        };
         638  +
        static LAST_NAME: MemberSchema = MemberSchema {
         639  +
            name: "lastName",
         640  +
            target: &prelude::STRING,
         641  +
        };
         642  +
        static AGE: MemberSchema = MemberSchema {
         643  +
            name: "age",
         644  +
            target: &prelude::INTEGER,
         645  +
        };
         646  +
         647  +
        struct TestSchema;
         648  +
        impl Schema for TestSchema {
         649  +
            fn shape_id(&self) -> &ShapeId {
         650  +
                static ID: std::sync::LazyLock<ShapeId> =
         651  +
                    std::sync::LazyLock::new(|| ShapeId::from_static("test#Test", "test", "Test"));
         652  +
                &ID
         653  +
            }
         654  +
            fn shape_type(&self) -> ShapeType {
         655  +
                ShapeType::Structure
         656  +
            }
         657  +
            fn traits(&self) -> &TraitMap {
         658  +
                static MAP: std::sync::LazyLock<TraitMap> = std::sync::LazyLock::new(TraitMap::new);
         659  +
                &MAP
         660  +
            }
         661  +
            fn member_schema(&self, name: &str) -> Option<&dyn Schema> {
         662  +
                match name {
         663  +
                    "firstName" => Some(&FIRST_NAME),
         664  +
                    "lastName" => Some(&LAST_NAME),
         665  +
                    "age" => Some(&AGE),
         666  +
                    _ => None,
         667  +
                }
         668  +
            }
         669  +
            fn member_schema_by_index(&self, index: usize) -> Option<(&str, &dyn Schema)> {
         670  +
                match index {
         671  +
                    0 => Some(("firstName", &FIRST_NAME)),
         672  +
                    1 => Some(("lastName", &LAST_NAME)),
         673  +
                    2 => Some(("age", &AGE)),
         674  +
                    _ => None,
         675  +
                }
         676  +
            }
         677  +
        }
         678  +
         679  +
        fn consume_person(
         680  +
            mut person: Person,
         681  +
            schema: &dyn Schema,
         682  +
            deser: &mut JsonDeserializer,
         683  +
        ) -> Result<Person, JsonDeserializerError> {
         684  +
            match schema.member_name() {
         685  +
                Some("firstName") => person.first_name = deser.read_string(schema)?,
         686  +
                Some("lastName") => person.last_name = deser.read_string(schema)?,
         687  +
                Some("age") => person.age = deser.read_integer(schema)?,
         688  +
                _ => {}
         689  +
            }
         690  +
            Ok(person)
         691  +
        }
         692  +
         693  +
        let json = br#"{"lastName":"Smithy","firstName":"Alice","age":30}"#;
         694  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         695  +
        let person = deser
         696  +
            .read_struct(&TestSchema, Person::default(), consume_person)
         697  +
            .unwrap();
         698  +
        assert_eq!(
         699  +
            person,
         700  +
            Person {
         701  +
                first_name: "Alice".to_string(),
         702  +
                last_name: "Smithy".to_string(),
         703  +
                age: 30
         704  +
            }
         705  +
        );
         706  +
         707  +
        let json =
         708  +
            br#"{"firstName":          "Alice","age":12345678,     "lastName":"\"Smithy\""}"#;
         709  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         710  +
        let person = deser
         711  +
            .read_struct(&TestSchema, Person::default(), consume_person)
         712  +
            .unwrap();
         713  +
        assert_eq!(
         714  +
            person,
         715  +
            Person {
         716  +
                first_name: "Alice".to_string(),
         717  +
                last_name: "\"Smithy\"".to_string(),
         718  +
                age: 12345678
         719  +
            }
         720  +
        );
         721  +
    }
         722  +
         723  +
    #[test]
         724  +
    fn test_read_list() {
         725  +
        let json = b"[1, 2, 3, 4, 5]";
         726  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         727  +
        let capacity = deser.container_size().unwrap_or(0);
         728  +
        let container = Vec::with_capacity(capacity);
         729  +
        let allocated_capacity = container.capacity();
         730  +
        let result = deser
         731  +
            .read_list(dummy_schema(), container, |mut vec, deser| {
         732  +
                vec.push(deser.read_integer(dummy_schema())?);
         733  +
                Ok(vec)
         734  +
            })
         735  +
            .unwrap();
         736  +
        assert_eq!(result, vec![1, 2, 3, 4, 5]);
         737  +
        // Ensure no more memory was allocated for the container
         738  +
        assert_eq!(result.capacity(), allocated_capacity);
         739  +
         740  +
        let json = b"[]";
         741  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         742  +
        let capacity = deser.container_size().unwrap_or(0);
         743  +
        let container = Vec::with_capacity(capacity);
         744  +
        let allocated_capacity = container.capacity();
         745  +
        let result = deser
         746  +
            .read_list(dummy_schema(), container, |mut vec, deser| {
         747  +
                vec.push(deser.read_integer(dummy_schema())?);
         748  +
                Ok(vec)
         749  +
            })
         750  +
            .unwrap();
         751  +
        assert_eq!(result, Vec::<i32>::new());
         752  +
        // Ensure no more memory was allocated for the container
         753  +
        assert_eq!(result.capacity(), allocated_capacity);
         754  +
         755  +
        let json = br#"["hello", "world"]"#;
         756  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         757  +
        let capacity = deser.container_size().unwrap_or(0);
         758  +
        let container = Vec::with_capacity(capacity);
         759  +
        let allocated_capacity = container.capacity();
         760  +
        let result = deser
         761  +
            .read_list(dummy_schema(), container, |mut vec, deser| {
         762  +
                vec.push(deser.read_string(dummy_schema())?);
         763  +
                Ok(vec)
         764  +
            })
         765  +
            .unwrap();
         766  +
        assert_eq!(result, vec!["hello", "world"]);
         767  +
        // Ensure no more memory was allocated for the container
         768  +
        assert_eq!(result.capacity(), allocated_capacity);
         769  +
    }
         770  +
         771  +
    #[test]
         772  +
    fn test_container_size() {
         773  +
        let deser = JsonDeserializer::new(b"[1, 2, 3, 4, 5]", JsonCodecSettings::default());
         774  +
        assert_eq!(deser.container_size(), Some(5));
         775  +
         776  +
        let deser = JsonDeserializer::new(b"[]", JsonCodecSettings::default());
         777  +
        assert_eq!(deser.container_size(), Some(0));
         778  +
         779  +
        let deser =
         780  +
            JsonDeserializer::new(br#"{"a": 1, "b": 2, "c": 3}"#, JsonCodecSettings::default());
         781  +
        assert_eq!(deser.container_size(), Some(3));
         782  +
         783  +
        let deser = JsonDeserializer::new(b"{}", JsonCodecSettings::default());
         784  +
        assert_eq!(deser.container_size(), Some(0));
         785  +
         786  +
        let deser =
         787  +
            JsonDeserializer::new(b"[[1, 2], [3, 4], [5, 6]]", JsonCodecSettings::default());
         788  +
        assert_eq!(deser.container_size(), Some(3));
         789  +
         790  +
        let deser = JsonDeserializer::new(b"42", JsonCodecSettings::default());
         791  +
        assert_eq!(deser.container_size(), None);
         792  +
    }
         793  +
         794  +
    #[test]
         795  +
    fn test_read_map() {
         796  +
        use std::collections::HashMap;
         797  +
         798  +
        let json = br#"{"a": 1, "b": 2, "c": 3}"#;
         799  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         800  +
        let calculated_capacity = deser.container_size().unwrap_or(0);
         801  +
        let container = HashMap::with_capacity(calculated_capacity);
         802  +
        let allocated_capacity = container.capacity();
         803  +
        let result = deser
         804  +
            .read_map(dummy_schema(), container, |mut map, key, deser| {
         805  +
                map.insert(key, deser.read_integer(dummy_schema())?);
         806  +
                Ok(map)
         807  +
            })
         808  +
            .unwrap();
         809  +
        assert_eq!(result.len(), 3);
         810  +
        assert_eq!(result.get("a"), Some(&1));
         811  +
        assert_eq!(result.get("b"), Some(&2));
         812  +
        assert_eq!(result.get("c"), Some(&3));
         813  +
        // Ensure no more memory was allocated for the container
         814  +
        assert_eq!(result.capacity(), allocated_capacity);
         815  +
         816  +
        let json = b"{}";
         817  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         818  +
        let calculated_capacity = deser.container_size().unwrap_or(0);
         819  +
        let container = HashMap::with_capacity(calculated_capacity);
         820  +
        let allocated_capacity = container.capacity();
         821  +
        let result = deser
         822  +
            .read_map(dummy_schema(), container, |mut map, key, deser| {
         823  +
                map.insert(key, deser.read_integer(dummy_schema())?);
         824  +
                Ok(map)
         825  +
            })
         826  +
            .unwrap();
         827  +
        assert_eq!(result, HashMap::<String, i32>::new());
         828  +
        // Ensure no more memory was allocated for the container
         829  +
        assert_eq!(result.capacity(), allocated_capacity);
         830  +
         831  +
        let json = br#"{"name": "Alice", "city": "Seattle"}"#;
         832  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
         833  +
        let calculated_capacity = deser.container_size().unwrap_or(0);
         834  +
        let container = HashMap::with_capacity(calculated_capacity);
         835  +
        let allocated_capacity = container.capacity();
         836  +
        let result = deser
         837  +
            .read_map(dummy_schema(), container, |mut map, key, deser| {
         838  +
                map.insert(key, deser.read_string(dummy_schema())?);
         839  +
                Ok(map)
         840  +
            })
         841  +
            .unwrap();
         842  +
        assert_eq!(result.len(), 2);
         843  +
        assert_eq!(result.get("name"), Some(&"Alice".to_string()));
         844  +
        assert_eq!(result.get("city"), Some(&"Seattle".to_string()));
         845  +
        // Ensure no more memory was allocated for the container
         846  +
        assert_eq!(result.capacity(), allocated_capacity);
         847  +
    }
         848  +
         849  +
    #[test]
         850  +
    fn test_nested_complex_deserialization() {
         851  +
        use aws_smithy_schema::{prelude, Schema, ShapeId, ShapeType, TraitMap};
         852  +
        use std::collections::HashMap;
         853  +
         854  +
        #[derive(Debug, Default, PartialEq)]
         855  +
        struct Address {
         856  +
            street: String,
         857  +
            city: String,
         858  +
            zip: i32,
         859  +
        }
         860  +
         861  +
        #[derive(Debug, Default, PartialEq)]
         862  +
        struct Company {
         863  +
            name: String,
         864  +
            employees: Vec<String>,
         865  +
            metadata: HashMap<String, i32>,
         866  +
            active: bool,
         867  +
        }
         868  +
         869  +
        #[derive(Debug, Default, PartialEq)]
         870  +
        struct User {
         871  +
            id: i64,
         872  +
            name: String,
         873  +
            scores: Vec<f64>,
         874  +
            address: Address,
         875  +
            companies: Vec<Company>,
         876  +
            tags: HashMap<String, String>,
         877  +
        }
         878  +
         879  +
        struct MemberSchema {
         880  +
            name: &'static str,
         881  +
            target: &'static dyn Schema,
         882  +
        }
         883  +
         884  +
        impl Schema for MemberSchema {
         885  +
            fn shape_id(&self) -> &ShapeId {
         886  +
                self.target.shape_id()
         887  +
            }
         888  +
            fn shape_type(&self) -> ShapeType {
         889  +
                self.target.shape_type()
         890  +
            }
         891  +
            fn traits(&self) -> &TraitMap {
         892  +
                self.target.traits()
         893  +
            }
         894  +
            fn member_name(&self) -> Option<&str> {
         895  +
                Some(self.name)
         896  +
            }
         897  +
        }
         898  +
         899  +
        static ADDR_STREET: MemberSchema = MemberSchema {
         900  +
            name: "street",
         901  +
            target: &prelude::STRING,
         902  +
        };
         903  +
        static ADDR_CITY: MemberSchema = MemberSchema {
         904  +
            name: "city",
         905  +
            target: &prelude::STRING,
         906  +
        };
         907  +
        static ADDR_ZIP: MemberSchema = MemberSchema {
         908  +
            name: "zip",
         909  +
            target: &prelude::INTEGER,
         910  +
        };
         911  +
         912  +
        struct AddressSchema;
         913  +
        impl Schema for AddressSchema {
         914  +
            fn shape_id(&self) -> &ShapeId {
         915  +
                static ID: std::sync::LazyLock<ShapeId> = std::sync::LazyLock::new(|| {
         916  +
                    ShapeId::from_static("test#Address", "test", "Address")
         917  +
                });
         918  +
                &ID
         919  +
            }
         920  +
            fn shape_type(&self) -> ShapeType {
         921  +
                ShapeType::Structure
         922  +
            }
         923  +
            fn traits(&self) -> &TraitMap {
         924  +
                static MAP: std::sync::LazyLock<TraitMap> = std::sync::LazyLock::new(TraitMap::new);
         925  +
                &MAP
         926  +
            }
         927  +
            fn member_schema(&self, name: &str) -> Option<&dyn Schema> {
         928  +
                match name {
         929  +
                    "street" => Some(&ADDR_STREET),
         930  +
                    "city" => Some(&ADDR_CITY),
         931  +
                    "zip" => Some(&ADDR_ZIP),
         932  +
                    _ => None,
         933  +
                }
         934  +
            }
         935  +
            fn member_schema_by_index(&self, index: usize) -> Option<(&str, &dyn Schema)> {
         936  +
                match index {
         937  +
                    0 => Some(("street", &ADDR_STREET)),
         938  +
                    1 => Some(("city", &ADDR_CITY)),
         939  +
                    2 => Some(("zip", &ADDR_ZIP)),
         940  +
                    _ => None,
         941  +
                }
         942  +
            }
         943  +
        }
         944  +
         945  +
        static COMP_NAME: MemberSchema = MemberSchema {
         946  +
            name: "name",
         947  +
            target: &prelude::STRING,
         948  +
        };
         949  +
        static COMP_ACTIVE: MemberSchema = MemberSchema {
         950  +
            name: "active",
         951  +
            target: &prelude::BOOLEAN,
         952  +
        };
         953  +
        static COMP_EMPLOYEES: MemberSchema = MemberSchema {
         954  +
            name: "employees",
         955  +
            target: &prelude::STRING,
         956  +
        };
         957  +
        static COMP_METADATA: MemberSchema = MemberSchema {
         958  +
            name: "metadata",
         959  +
            target: &prelude::STRING,
         960  +
        };
         961  +
         962  +
        struct CompanySchema;
         963  +
        impl Schema for CompanySchema {
         964  +
            fn shape_id(&self) -> &ShapeId {
         965  +
                static ID: std::sync::LazyLock<ShapeId> = std::sync::LazyLock::new(|| {
         966  +
                    ShapeId::from_static("test#Company", "test", "Company")
         967  +
                });
         968  +
                &ID
         969  +
            }
         970  +
            fn shape_type(&self) -> ShapeType {
         971  +
                ShapeType::Structure
         972  +
            }
         973  +
            fn traits(&self) -> &TraitMap {
         974  +
                static MAP: std::sync::LazyLock<TraitMap> = std::sync::LazyLock::new(TraitMap::new);
         975  +
                &MAP
         976  +
            }
         977  +
            fn member_schema(&self, name: &str) -> Option<&dyn Schema> {
         978  +
                match name {
         979  +
                    "name" => Some(&COMP_NAME),
         980  +
                    "active" => Some(&COMP_ACTIVE),
         981  +
                    "employees" => Some(&COMP_EMPLOYEES),
         982  +
                    "metadata" => Some(&COMP_METADATA),
         983  +
                    _ => None,
         984  +
                }
         985  +
            }
         986  +
            fn member_schema_by_index(&self, index: usize) -> Option<(&str, &dyn Schema)> {
         987  +
                match index {
         988  +
                    0 => Some(("name", &COMP_NAME)),
         989  +
                    1 => Some(("active", &COMP_ACTIVE)),
         990  +
                    _ => None,
         991  +
                }
         992  +
            }
         993  +
        }
         994  +
         995  +
        static USER_ID: MemberSchema = MemberSchema {
         996  +
            name: "id",
         997  +
            target: &prelude::LONG,
         998  +
        };
         999  +
        static USER_NAME: MemberSchema = MemberSchema {
        1000  +
            name: "name",
        1001  +
            target: &prelude::STRING,
        1002  +
        };
        1003  +
        static USER_SCORES: MemberSchema = MemberSchema {
        1004  +
            name: "scores",
        1005  +
            target: &prelude::STRING,
        1006  +
        };
        1007  +
        static USER_ADDRESS: MemberSchema = MemberSchema {
        1008  +
            name: "address",
        1009  +
            target: &prelude::STRING,
        1010  +
        };
        1011  +
        static USER_COMPANIES: MemberSchema = MemberSchema {
        1012  +
            name: "companies",
        1013  +
            target: &prelude::STRING,
        1014  +
        };
        1015  +
        static USER_TAGS: MemberSchema = MemberSchema {
        1016  +
            name: "tags",
        1017  +
            target: &prelude::STRING,
        1018  +
        };
        1019  +
        1020  +
        struct UserSchema;
        1021  +
        impl Schema for UserSchema {
        1022  +
            fn shape_id(&self) -> &ShapeId {
        1023  +
                static ID: std::sync::LazyLock<ShapeId> =
        1024  +
                    std::sync::LazyLock::new(|| ShapeId::from_static("test#User", "test", "User"));
        1025  +
                &ID
        1026  +
            }
        1027  +
            fn shape_type(&self) -> ShapeType {
        1028  +
                ShapeType::Structure
        1029  +
            }
        1030  +
            fn traits(&self) -> &TraitMap {
        1031  +
                static MAP: std::sync::LazyLock<TraitMap> = std::sync::LazyLock::new(TraitMap::new);
        1032  +
                &MAP
        1033  +
            }
        1034  +
            fn member_schema(&self, name: &str) -> Option<&dyn Schema> {
        1035  +
                match name {
        1036  +
                    "id" => Some(&USER_ID),
        1037  +
                    "name" => Some(&USER_NAME),
        1038  +
                    "scores" => Some(&USER_SCORES),
        1039  +
                    "address" => Some(&USER_ADDRESS),
        1040  +
                    "companies" => Some(&USER_COMPANIES),
        1041  +
                    "tags" => Some(&USER_TAGS),
        1042  +
                    _ => None,
        1043  +
                }
        1044  +
            }
        1045  +
            fn member_schema_by_index(&self, index: usize) -> Option<(&str, &dyn Schema)> {
        1046  +
                match index {
        1047  +
                    0 => Some(("id", &USER_ID)),
        1048  +
                    1 => Some(("name", &USER_NAME)),
        1049  +
                    _ => None,
        1050  +
                }
        1051  +
            }
        1052  +
        }
        1053  +
        1054  +
        fn consume_address(
        1055  +
            mut addr: Address,
        1056  +
            schema: &dyn Schema,
        1057  +
            deser: &mut JsonDeserializer,
        1058  +
        ) -> Result<Address, JsonDeserializerError> {
        1059  +
            match schema.member_name() {
        1060  +
                Some("street") => addr.street = deser.read_string(schema)?,
        1061  +
                Some("city") => addr.city = deser.read_string(schema)?,
        1062  +
                Some("zip") => addr.zip = deser.read_integer(schema)?,
        1063  +
                _ => {}
        1064  +
            }
        1065  +
            Ok(addr)
        1066  +
        }
        1067  +
        1068  +
        fn consume_company(
        1069  +
            mut comp: Company,
        1070  +
            schema: &dyn Schema,
        1071  +
            deser: &mut JsonDeserializer,
        1072  +
        ) -> Result<Company, JsonDeserializerError> {
        1073  +
            match schema.member_name() {
        1074  +
                Some("name") => comp.name = deser.read_string(schema)?,
        1075  +
                Some("active") => comp.active = deser.read_boolean(schema)?,
        1076  +
                Some("employees") => {
        1077  +
                    comp.employees = deser.read_list(schema, Vec::new(), |mut v, d| {
        1078  +
                        v.push(d.read_string(dummy_schema())?);
        1079  +
                        Ok(v)
        1080  +
                    })?
        1081  +
                }
        1082  +
                Some("metadata") => {
        1083  +
                    comp.metadata = deser.read_map(schema, HashMap::new(), |mut m, k, d| {
        1084  +
                        m.insert(k, d.read_integer(dummy_schema())?);
        1085  +
                        Ok(m)
        1086  +
                    })?
        1087  +
                }
        1088  +
                _ => {}
        1089  +
            }
        1090  +
            Ok(comp)
        1091  +
        }
        1092  +
        1093  +
        fn consume_user(
        1094  +
            mut user: User,
        1095  +
            schema: &dyn Schema,
        1096  +
            deser: &mut JsonDeserializer,
        1097  +
        ) -> Result<User, JsonDeserializerError> {
        1098  +
            match schema.member_name() {
        1099  +
                Some("id") => user.id = deser.read_long(schema)?,
        1100  +
                Some("name") => user.name = deser.read_string(schema)?,
        1101  +
                Some("scores") => {
        1102  +
                    user.scores = deser.read_list(schema, Vec::new(), |mut v, d| {
        1103  +
                        v.push(d.read_double(dummy_schema())?);
        1104  +
                        Ok(v)
        1105  +
                    })?
        1106  +
                }
        1107  +
                Some("address") => {
        1108  +
                    user.address =
        1109  +
                        deser.read_struct(&AddressSchema, Address::default(), consume_address)?
        1110  +
                }
        1111  +
                Some("companies") => {
        1112  +
                    user.companies = deser.read_list(schema, Vec::new(), |mut v, d| {
        1113  +
                        v.push(d.read_struct(
        1114  +
                            &CompanySchema,
        1115  +
                            Company::default(),
        1116  +
                            consume_company,
        1117  +
                        )?);
        1118  +
                        Ok(v)
        1119  +
                    })?
        1120  +
                }
        1121  +
                Some("tags") => {
        1122  +
                    user.tags = deser.read_map(schema, HashMap::new(), |mut m, k, d| {
        1123  +
                        m.insert(k, d.read_string(dummy_schema())?);
        1124  +
                        Ok(m)
        1125  +
                    })?
        1126  +
                }
        1127  +
                _ => {}
        1128  +
            }
        1129  +
            Ok(user)
        1130  +
        }
        1131  +
        1132  +
        let json = br#"{
        1133  +
            "id": 12345,
        1134  +
            "name": "John Doe",
        1135  +
            "scores": [95.5, 87.3, 92.1],
        1136  +
            "address": {
        1137  +
                "street": "123 Main St",
        1138  +
                "city": "Seattle",
        1139  +
                "zip": 98101
        1140  +
            },
        1141  +
            "companies": [
        1142  +
                {
        1143  +
                    "name": "TechCorp",
        1144  +
                    "employees": ["Alice", "Bob"],
        1145  +
                    "metadata": {"founded": 2010, "size": 500},
        1146  +
                    "active": true
        1147  +
                },
        1148  +
                {
        1149  +
                    "name": "StartupInc",
        1150  +
                    "employees": ["Charlie"],
        1151  +
                    "metadata": {"founded": 2020},
        1152  +
                    "active": false
        1153  +
                }
        1154  +
            ],
        1155  +
            "tags": {"role": "admin", "level": "senior"}
        1156  +
        }"#;
        1157  +
        1158  +
        let mut deser = JsonDeserializer::new(json, JsonCodecSettings::default());
        1159  +
        let user = deser
        1160  +
            .read_struct(&UserSchema, User::default(), consume_user)
        1161  +
            .unwrap();
        1162  +
        1163  +
        assert_eq!(user.id, 12345);
        1164  +
        assert_eq!(user.name, "John Doe");
        1165  +
        assert_eq!(user.scores, vec![95.5, 87.3, 92.1]);
        1166  +
        assert_eq!(user.address.street, "123 Main St");
        1167  +
        assert_eq!(user.address.city, "Seattle");
        1168  +
        assert_eq!(user.address.zip, 98101);
        1169  +
        assert_eq!(user.companies.len(), 2);
        1170  +
        assert_eq!(user.companies[0].name, "TechCorp");
        1171  +
        assert_eq!(user.companies[0].employees, vec!["Alice", "Bob"]);
        1172  +
        assert_eq!(user.companies[0].metadata.get("founded"), Some(&2010));
        1173  +
        assert_eq!(user.companies[0].metadata.get("size"), Some(&500));
        1174  +
        assert_eq!(user.companies[0].active, true);
        1175  +
        assert_eq!(user.companies[1].name, "StartupInc");
        1176  +
        assert_eq!(user.companies[1].employees, vec!["Charlie"]);
        1177  +
        assert_eq!(user.companies[1].metadata.get("founded"), Some(&2020));
        1178  +
        assert_eq!(user.companies[1].active, false);
        1179  +
        assert_eq!(user.tags.get("role"), Some(&"admin".to_string()));
        1180  +
        assert_eq!(user.tags.get("level"), Some(&"senior".to_string()));
        1181  +
    }
        1182  +
}