AWS SDK

AWS SDK

rev. 8da168d5fec7572c2f9dada1175b4c72d0140db8

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