AWS SDK

AWS SDK

rev. 163d4d6410694aaf071424777ecbecd050925f36 (ignoring whitespace)

Files changed:

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

@@ -1,1 +398,703 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
    6      6   
//! JSON deserializer implementation.
    7      7   
    8      8   
use aws_smithy_schema::serde::SerdeError;
    9      9   
use aws_smithy_schema::serde::ShapeDeserializer;
   10     10   
use aws_smithy_schema::Schema;
   11         -
use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime, Document, Number};
          11  +
use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime, Document};
   12     12   
   13     13   
use crate::codec::JsonCodecSettings;
   14     14   
use crate::deserialize::{json_token_iter, Token};
   15     15   
   16     16   
use std::sync::Arc;
   17     17   
   18     18   
/// JSON deserializer that implements the ShapeDeserializer trait.
   19     19   
pub struct JsonDeserializer<'a> {
   20     20   
    input: &'a [u8],
   21     21   
    position: usize,
   22     22   
    settings: Arc<JsonCodecSettings>,
   23     23   
}
   24     24   
   25     25   
impl<'a> JsonDeserializer<'a> {
   26     26   
    /// Creates a new JSON deserializer with the given settings.
   27     27   
    pub(crate) fn new(input: &'a [u8], settings: Arc<JsonCodecSettings>) -> Self {
   28     28   
        Self {
   29     29   
            input,
   30     30   
            position: 0,
   31     31   
            settings,
   32     32   
        }
   33     33   
    }
   34     34   
   35     35   
    /// Resolves a JSON field name to a member schema.
   36     36   
    fn resolve_member<'s>(&self, schema: &'s Schema, field_name: &str) -> Option<&'s Schema> {
   37     37   
        self.settings.field_to_member(schema, field_name)
   38     38   
    }
   39     39   
   40     40   
    fn remaining(&self) -> &[u8] {
   41     41   
        &self.input[self.position..]
   42     42   
    }
   43     43   
   44     44   
    fn advance_by(&mut self, n: usize) {
   45     45   
        self.position += n;
   46     46   
    }
          47  +
          48  +
    /// Parse a JSON quoted string key directly from bytes, advancing past it.
          49  +
    /// Assumes the current position is at the opening `"`.
          50  +
    /// Returns a borrowed `&str` when no escape sequences are present (common case),
          51  +
    /// avoiding a heap allocation per JSON key.
          52  +
    fn parse_key(&mut self) -> Result<std::borrow::Cow<'a, str>, SerdeError> {
          53  +
        let start = self.position + 1; // skip opening quote
          54  +
        self.position += 1;
          55  +
        let input = self.input;
          56  +
        let remaining = &input[start..];
          57  +
        let mut i = 0;
          58  +
        let mut has_escapes = false;
          59  +
        while i < remaining.len() {
          60  +
            match remaining[i] {
          61  +
                b'"' => break,
          62  +
                b'\\' => {
          63  +
                    has_escapes = true;
          64  +
                    i += 2;
          65  +
                }
          66  +
                _ => i += 1,
          67  +
            }
          68  +
        }
          69  +
        self.position = start + i + 1; // advance past key bytes + closing quote
          70  +
        let key_bytes = &input[start..start + i];
          71  +
        if has_escapes {
          72  +
            let raw = std::str::from_utf8(key_bytes).map_err(|e| SerdeError::InvalidInput {
          73  +
                message: e.to_string(),
          74  +
            })?;
          75  +
            Ok(std::borrow::Cow::Owned(
          76  +
                crate::escape::unescape_string(raw)
          77  +
                    .map_err(|e| SerdeError::InvalidInput {
          78  +
                        message: e.to_string(),
          79  +
                    })?
          80  +
                    .into_owned(),
          81  +
            ))
          82  +
        } else {
          83  +
            Ok(std::borrow::Cow::Borrowed(
          84  +
                std::str::from_utf8(key_bytes).map_err(|e| SerdeError::InvalidInput {
          85  +
                    message: e.to_string(),
          86  +
                })?,
          87  +
            ))
          88  +
        }
          89  +
    }
   47     90   
}
   48     91   
   49     92   
impl<'a> ShapeDeserializer for JsonDeserializer<'a> {
   50         -
    fn read_struct<T, F>(
          93  +
    fn read_struct(
   51     94   
        &mut self,
   52     95   
        schema: &Schema,
   53         -
        mut state: T,
   54         -
        mut consumer: F,
   55         -
    ) -> Result<T, SerdeError>
   56         -
    where
   57         -
        F: FnMut(T, &Schema, &mut Self) -> Result<T, SerdeError>,
   58         -
    {
          96  +
        consumer: &mut dyn FnMut(&Schema, &mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
          97  +
    ) -> Result<(), SerdeError> {
   59     98   
        // Expect opening brace
   60     99   
        self.skip_whitespace();
         100  +
        if self.remaining().is_empty() {
         101  +
            // Treat empty input as an empty object (e.g., empty HTTP response body)
         102  +
            return Ok(());
         103  +
        }
   61    104   
        if self.remaining().first() != Some(&b'{') {
   62    105   
            return Err(SerdeError::TypeMismatch {
   63    106   
                message: "expected object".into(),
   64    107   
            });
   65    108   
        }
   66    109   
        self.advance_by(1);
   67    110   
   68    111   
        loop {
   69    112   
            self.skip_whitespace();
   70    113   
   71    114   
            // Check for end of object
   72    115   
            if self.remaining().first() == Some(&b'}') {
   73    116   
                self.advance_by(1);
   74    117   
                break;
   75    118   
            }
   76    119   
   77    120   
            // Expect a key (quoted string)
   78    121   
            if self.remaining().first() != Some(&b'"') {
   79    122   
                return Err(SerdeError::InvalidInput {
   80    123   
                    message: "expected object key".into(),
   81    124   
                });
   82    125   
            }
   83    126   
   84         -
            // Parse the key using the token iterator
   85         -
            let mut iter = json_token_iter(self.remaining());
   86         -
            let key_str = match iter.next() {
   87         -
                Some(Ok(Token::ValueString { value, .. })) => {
   88         -
                    let key_len = value.as_escaped_str().len();
   89         -
                    let key = value
   90         -
                        .to_unescaped()
   91         -
                        .map_err(|e| SerdeError::InvalidInput {
   92         -
                            message: e.to_string(),
   93         -
                        })?
   94         -
                        .into_owned();
   95         -
                    // Advance past opening quote + key + closing quote
   96         -
                    self.advance_by(key_len + 2);
   97         -
                    key
   98         -
                }
   99         -
                _ => {
  100         -
                    return Err(SerdeError::InvalidInput {
  101         -
                        message: "expected object key".into(),
  102         -
                    })
  103         -
                }
  104         -
            };
         127  +
            // Parse the key directly from bytes
         128  +
            let key_str = self.parse_key()?;
  105    129   
  106    130   
            // Skip whitespace and expect colon
  107    131   
            self.skip_whitespace();
  108    132   
            if self.remaining().first() != Some(&b':') {
  109    133   
                return Err(SerdeError::InvalidInput {
  110    134   
                    message: "expected colon after key".into(),
  111    135   
                });
  112    136   
            }
  113    137   
            self.advance_by(1);
  114    138   
            self.skip_whitespace();
  115    139   
  116         -
            // Process the value
  117         -
            if let Some(member_schema) = self.resolve_member(schema, &key_str) {
  118         -
                state = consumer(state, member_schema, self)?;
         140  +
            // Process the value — skip nulls (they represent absent optional members)
         141  +
            let rem = self.remaining();
         142  +
            if rem.starts_with(b"null") && !rem.get(4).is_some_and(|b| b.is_ascii_alphanumeric()) {
         143  +
                self.advance_by(4);
         144  +
            } else if let Some(member_schema) = self.resolve_member(schema, &key_str) {
         145  +
                consumer(member_schema, self)?;
  119    146   
            } else {
  120    147   
                self.skip_value()?;
  121    148   
            }
  122    149   
        }
  123    150   
  124         -
        Ok(state)
         151  +
        Ok(())
  125    152   
    }
  126    153   
  127         -
    fn read_list<T, F>(
         154  +
    fn read_list(
  128    155   
        &mut self,
  129    156   
        _schema: &Schema,
  130         -
        mut state: T,
  131         -
        mut consumer: F,
  132         -
    ) -> Result<T, SerdeError>
  133         -
    where
  134         -
        F: FnMut(T, &mut Self) -> Result<T, SerdeError>,
  135         -
    {
         157  +
        consumer: &mut dyn FnMut(&mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
         158  +
    ) -> Result<(), SerdeError> {
  136    159   
        self.skip_whitespace();
  137    160   
        if self.remaining().first() != Some(&b'[') {
  138    161   
            return Err(SerdeError::TypeMismatch {
  139    162   
                message: "expected array".into(),
  140    163   
            });
  141    164   
        }
  142    165   
        self.advance_by(1);
  143    166   
  144    167   
        loop {
  145    168   
            self.skip_whitespace();
  146    169   
            if self.remaining().first() == Some(&b']') {
  147    170   
                self.advance_by(1);
  148    171   
                break;
  149    172   
            }
  150         -
            state = consumer(state, self)?;
         173  +
            consumer(self)?;
  151    174   
        }
  152    175   
  153         -
        Ok(state)
         176  +
        Ok(())
  154    177   
    }
  155    178   
  156         -
    fn read_map<T, F>(
         179  +
    fn read_map(
  157    180   
        &mut self,
  158    181   
        _schema: &Schema,
  159         -
        mut state: T,
  160         -
        mut consumer: F,
  161         -
    ) -> Result<T, SerdeError>
  162         -
    where
  163         -
        F: FnMut(T, String, &mut Self) -> Result<T, SerdeError>,
  164         -
    {
         182  +
        consumer: &mut dyn FnMut(String, &mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
         183  +
    ) -> Result<(), SerdeError> {
  165    184   
        self.skip_whitespace();
  166    185   
        if self.remaining().first() != Some(&b'{') {
  167    186   
            return Err(SerdeError::TypeMismatch {
  168    187   
                message: "expected object".into(),
  169    188   
            });
  170    189   
        }
  171    190   
        self.advance_by(1);
  172    191   
  173    192   
        loop {
  174    193   
            self.skip_whitespace();
  175    194   
            if self.remaining().first() == Some(&b'}') {
  176    195   
                self.advance_by(1);
  177    196   
                break;
  178    197   
            }
  179    198   
  180    199   
            if self.remaining().first() != Some(&b'"') {
  181    200   
                return Err(SerdeError::InvalidInput {
  182    201   
                    message: "expected key".into(),
  183    202   
                });
  184    203   
            }
  185    204   
  186         -
            let mut iter = json_token_iter(self.remaining());
  187         -
            let key = match iter.next() {
  188         -
                Some(Ok(Token::ValueString { value, .. })) => {
  189         -
                    let len = value.as_escaped_str().len();
  190         -
                    let key = value
  191         -
                        .to_unescaped()
  192         -
                        .map_err(|e| SerdeError::InvalidInput {
  193         -
                            message: e.to_string(),
  194         -
                        })?
  195         -
                        .into_owned();
  196         -
                    self.advance_by(len + 2);
  197         -
                    key
  198         -
                }
  199         -
                _ => {
  200         -
                    return Err(SerdeError::InvalidInput {
  201         -
                        message: "expected key".into(),
  202         -
                    })
  203         -
                }
  204         -
            };
         205  +
            let key = self.parse_key()?;
  205    206   
  206    207   
            self.skip_whitespace();
  207    208   
            if self.remaining().first() != Some(&b':') {
  208    209   
                return Err(SerdeError::InvalidInput {
  209    210   
                    message: "expected colon".into(),
  210    211   
                });
  211    212   
            }
  212    213   
            self.advance_by(1);
  213    214   
            self.skip_whitespace();
  214    215   
  215         -
            state = consumer(state, key, self)?;
         216  +
            consumer(key.into_owned(), self)?;
  216    217   
        }
  217    218   
  218         -
        Ok(state)
         219  +
        Ok(())
  219    220   
    }
  220    221   
  221    222   
    fn read_boolean(&mut self, _schema: &Schema) -> Result<bool, SerdeError> {
  222         -
        let mut iter = json_token_iter(self.remaining());
  223         -
        match iter.next() {
  224         -
            Some(Ok(Token::ValueBool { value, .. })) => {
  225         -
                self.advance_by(if value { 4 } else { 5 });
  226         -
                Ok(value)
  227         -
            }
  228         -
            _ => Err(SerdeError::TypeMismatch {
         223  +
        self.skip_whitespace();
         224  +
        let rem = self.remaining();
         225  +
        if rem.starts_with(b"true") {
         226  +
            self.advance_by(4);
         227  +
            Ok(true)
         228  +
        } else if rem.starts_with(b"false") {
         229  +
            self.advance_by(5);
         230  +
            Ok(false)
         231  +
        } else {
         232  +
            Err(SerdeError::TypeMismatch {
  229    233   
                message: "expected boolean".into(),
  230         -
            }),
         234  +
            })
  231    235   
        }
  232    236   
    }
  233    237   
  234    238   
    fn read_byte(&mut self, _schema: &Schema) -> Result<i8, SerdeError> {
  235    239   
        self.read_integer_value().and_then(|n| {
  236    240   
            i8::try_from(n).map_err(|_| SerdeError::InvalidInput {
  237    241   
                message: "value out of range for byte".into(),
  238    242   
            })
  239    243   
        })
  240    244   
    }
  241    245   
  242    246   
    fn read_short(&mut self, _schema: &Schema) -> Result<i16, SerdeError> {
  243    247   
        self.read_integer_value().and_then(|n| {
  244    248   
            i16::try_from(n).map_err(|_| SerdeError::InvalidInput {
  245    249   
                message: "value out of range for short".into(),
  246    250   
            })
  247    251   
        })
  248    252   
    }
  249    253   
  250    254   
    fn read_integer(&mut self, _schema: &Schema) -> Result<i32, SerdeError> {
  251    255   
        self.read_integer_value().and_then(|n| {
  252    256   
            i32::try_from(n).map_err(|_| SerdeError::InvalidInput {
  253    257   
                message: "value out of range for integer".into(),
  254    258   
            })
  255    259   
        })
  256    260   
    }
  257    261   
  258    262   
    fn read_long(&mut self, _schema: &Schema) -> Result<i64, SerdeError> {
  259    263   
        self.read_integer_value()
  260    264   
    }
  261    265   
  262    266   
    fn read_float(&mut self, _schema: &Schema) -> Result<f32, SerdeError> {
  263    267   
        self.read_float_value().map(|f| f as f32)
  264    268   
    }
  265    269   
  266    270   
    fn read_double(&mut self, _schema: &Schema) -> Result<f64, SerdeError> {
  267    271   
        self.read_float_value()
  268    272   
    }
  269    273   
  270    274   
    fn read_big_integer(&mut self, _schema: &Schema) -> Result<BigInteger, SerdeError> {
  271    275   
        use std::str::FromStr;
  272         -
        let mut iter = json_token_iter(self.remaining());
  273         -
        match iter.next() {
  274         -
            Some(Ok(Token::ValueNumber { .. })) => {
         276  +
        self.skip_whitespace();
         277  +
        match self.remaining().first() {
         278  +
            Some(b'-') | Some(b'0'..=b'9') => {
         279  +
                let start = self.position;
  275    280   
                self.consume_number();
  276         -
                BigInteger::from_str("0").map_err(|e| SerdeError::InvalidInput {
         281  +
                let num_str =
         282  +
                    std::str::from_utf8(&self.input[start..self.position]).map_err(|e| {
         283  +
                        SerdeError::InvalidInput {
         284  +
                            message: e.to_string(),
         285  +
                        }
         286  +
                    })?;
         287  +
                BigInteger::from_str(num_str).map_err(|e| SerdeError::InvalidInput {
  277    288   
                    message: e.to_string(),
  278    289   
                })
  279    290   
            }
  280    291   
            _ => Err(SerdeError::TypeMismatch {
  281    292   
                message: "expected number".into(),
  282    293   
            }),
  283    294   
        }
  284    295   
    }
  285    296   
  286    297   
    fn read_big_decimal(&mut self, _schema: &Schema) -> Result<BigDecimal, SerdeError> {
  287    298   
        use std::str::FromStr;
  288         -
        let mut iter = json_token_iter(self.remaining());
  289         -
        match iter.next() {
  290         -
            Some(Ok(Token::ValueNumber { .. })) => {
         299  +
        self.skip_whitespace();
         300  +
        match self.remaining().first() {
         301  +
            Some(b'-') | Some(b'0'..=b'9') => {
         302  +
                let start = self.position;
  291    303   
                self.consume_number();
  292         -
                BigDecimal::from_str("0").map_err(|e| SerdeError::InvalidInput {
         304  +
                let num_str =
         305  +
                    std::str::from_utf8(&self.input[start..self.position]).map_err(|e| {
         306  +
                        SerdeError::InvalidInput {
         307  +
                            message: e.to_string(),
         308  +
                        }
         309  +
                    })?;
         310  +
                BigDecimal::from_str(num_str).map_err(|e| SerdeError::InvalidInput {
  293    311   
                    message: e.to_string(),
  294    312   
                })
  295    313   
            }
  296    314   
            _ => Err(SerdeError::TypeMismatch {
  297    315   
                message: "expected number".into(),
  298    316   
            }),
  299    317   
        }
  300    318   
    }
  301    319   
  302    320   
    fn read_string(&mut self, _schema: &Schema) -> Result<String, SerdeError> {
  303         -
        let mut iter = json_token_iter(self.remaining());
  304         -
        match iter.next() {
  305         -
            Some(Ok(Token::ValueString { value, .. })) => {
  306         -
                let len = value.as_escaped_str().len();
  307         -
                let result = value.to_unescaped().map(|s| s.into_owned()).map_err(|e| {
         321  +
        self.skip_whitespace();
         322  +
        let pos = self.position;
         323  +
        let input = self.input;
         324  +
        let rem = &input[pos..];
         325  +
        if rem.first() != Some(&b'"') {
         326  +
            return Err(SerdeError::TypeMismatch {
         327  +
                message: "expected string".into(),
         328  +
            });
         329  +
        }
         330  +
        // Scan for end of string, tracking whether escapes are present
         331  +
        let mut i = 1;
         332  +
        let mut has_escape = false;
         333  +
        while i < rem.len() {
         334  +
            if rem[i] == b'\\' {
         335  +
                has_escape = true;
         336  +
                i += 2;
         337  +
            } else if rem[i] == b'"' {
         338  +
                let raw = &input[pos + 1..pos + i];
         339  +
                self.position = pos + i + 1;
         340  +
                if !has_escape {
         341  +
                    return std::str::from_utf8(raw).map(|s| s.to_owned()).map_err(|e| {
  308    342   
                        SerdeError::InvalidInput {
  309    343   
                            message: e.to_string(),
  310    344   
                        }
         345  +
                    });
         346  +
                }
         347  +
                let s = std::str::from_utf8(raw).map_err(|e| SerdeError::InvalidInput {
         348  +
                    message: e.to_string(),
  311    349   
                })?;
  312         -
                self.advance_by(len + 2);
  313         -
                Ok(result)
         350  +
                return crate::deserialize::EscapedStr::new(s)
         351  +
                    .to_unescaped()
         352  +
                    .map(|s| s.into_owned())
         353  +
                    .map_err(|e| SerdeError::InvalidInput {
         354  +
                        message: e.to_string(),
         355  +
                    });
         356  +
            } else {
         357  +
                i += 1;
  314    358   
            }
  315         -
            _ => Err(SerdeError::TypeMismatch {
  316         -
                message: "expected string".into(),
  317         -
            }),
  318    359   
        }
         360  +
        Err(SerdeError::InvalidInput {
         361  +
            message: "unterminated string".into(),
         362  +
        })
  319    363   
    }
  320    364   
  321    365   
    fn read_blob(&mut self, _schema: &Schema) -> Result<Blob, SerdeError> {
  322    366   
        let s = self.read_string(_schema)?;
  323    367   
        let decoded =
  324    368   
            aws_smithy_types::base64::decode(&s).map_err(|e| SerdeError::InvalidInput {
  325    369   
                message: format!("invalid base64: {}", e),
  326    370   
            })?;
  327    371   
        Ok(Blob::new(decoded))
  328    372   
    }
  329    373   
  330         -
    fn read_timestamp(&mut self, _schema: &Schema) -> Result<DateTime, SerdeError> {
  331         -
        let mut iter = json_token_iter(self.remaining());
  332         -
        match iter.next() {
  333         -
            Some(Ok(Token::ValueNumber {
  334         -
                value: Number::PosInt(n),
  335         -
                ..
  336         -
            })) => {
  337         -
                self.consume_number();
  338         -
                Ok(DateTime::from_secs(n as i64))
         374  +
    fn read_string_list(&mut self, _schema: &Schema) -> Result<Vec<String>, SerdeError> {
         375  +
        self.skip_whitespace();
         376  +
        if self.remaining().first() != Some(&b'[') {
         377  +
            return Err(SerdeError::TypeMismatch {
         378  +
                message: "expected array".into(),
         379  +
            });
         380  +
        }
         381  +
        self.advance_by(1);
         382  +
        let mut out = Vec::new();
         383  +
        loop {
         384  +
            self.skip_whitespace();
         385  +
            if self.remaining().first() == Some(&b']') {
         386  +
                self.advance_by(1);
         387  +
                break;
  339    388   
            }
  340         -
            Some(Ok(Token::ValueNumber {
  341         -
                value: Number::NegInt(n),
  342         -
                ..
  343         -
            })) => {
         389  +
            out.push(self.read_string(_schema)?);
         390  +
        }
         391  +
        Ok(out)
         392  +
    }
         393  +
         394  +
    fn read_blob_list(&mut self, _schema: &Schema) -> Result<Vec<Blob>, SerdeError> {
         395  +
        self.skip_whitespace();
         396  +
        if self.remaining().first() != Some(&b'[') {
         397  +
            return Err(SerdeError::TypeMismatch {
         398  +
                message: "expected array".into(),
         399  +
            });
         400  +
        }
         401  +
        self.advance_by(1);
         402  +
        let mut out = Vec::new();
         403  +
        loop {
         404  +
            self.skip_whitespace();
         405  +
            if self.remaining().first() == Some(&b']') {
         406  +
                self.advance_by(1);
         407  +
                break;
         408  +
            }
         409  +
            out.push(self.read_blob(_schema)?);
         410  +
        }
         411  +
        Ok(out)
         412  +
    }
         413  +
         414  +
    fn read_integer_list(&mut self, _schema: &Schema) -> Result<Vec<i32>, SerdeError> {
         415  +
        self.skip_whitespace();
         416  +
        if self.remaining().first() != Some(&b'[') {
         417  +
            return Err(SerdeError::TypeMismatch {
         418  +
                message: "expected array".into(),
         419  +
            });
         420  +
        }
         421  +
        self.advance_by(1);
         422  +
        let mut out = Vec::new();
         423  +
        loop {
         424  +
            self.skip_whitespace();
         425  +
            if self.remaining().first() == Some(&b']') {
         426  +
                self.advance_by(1);
         427  +
                break;
         428  +
            }
         429  +
            out.push(self.read_integer(_schema)?);
         430  +
        }
         431  +
        Ok(out)
         432  +
    }
         433  +
         434  +
    fn read_long_list(&mut self, _schema: &Schema) -> Result<Vec<i64>, SerdeError> {
         435  +
        self.skip_whitespace();
         436  +
        if self.remaining().first() != Some(&b'[') {
         437  +
            return Err(SerdeError::TypeMismatch {
         438  +
                message: "expected array".into(),
         439  +
            });
         440  +
        }
         441  +
        self.advance_by(1);
         442  +
        let mut out = Vec::new();
         443  +
        loop {
         444  +
            self.skip_whitespace();
         445  +
            if self.remaining().first() == Some(&b']') {
         446  +
                self.advance_by(1);
         447  +
                break;
         448  +
            }
         449  +
            out.push(self.read_long(_schema)?);
         450  +
        }
         451  +
        Ok(out)
         452  +
    }
         453  +
         454  +
    fn read_string_string_map(
         455  +
        &mut self,
         456  +
        _schema: &Schema,
         457  +
    ) -> Result<std::collections::HashMap<String, String>, SerdeError> {
         458  +
        self.skip_whitespace();
         459  +
        if self.remaining().first() != Some(&b'{') {
         460  +
            return Err(SerdeError::TypeMismatch {
         461  +
                message: "expected object".into(),
         462  +
            });
         463  +
        }
         464  +
        self.advance_by(1);
         465  +
        let mut out = std::collections::HashMap::new();
         466  +
        loop {
         467  +
            self.skip_whitespace();
         468  +
            if self.remaining().first() == Some(&b'}') {
         469  +
                self.advance_by(1);
         470  +
                break;
         471  +
            }
         472  +
            if self.remaining().first() != Some(&b'"') {
         473  +
                return Err(SerdeError::InvalidInput {
         474  +
                    message: "expected key".into(),
         475  +
                });
         476  +
            }
         477  +
            let key = self.parse_key()?;
         478  +
            self.skip_whitespace();
         479  +
            if self.remaining().first() != Some(&b':') {
         480  +
                return Err(SerdeError::InvalidInput {
         481  +
                    message: "expected colon".into(),
         482  +
                });
         483  +
            }
         484  +
            self.advance_by(1);
         485  +
            self.skip_whitespace();
         486  +
            let val = self.read_string(_schema)?;
         487  +
            out.insert(key.into_owned(), val);
         488  +
        }
         489  +
        Ok(out)
         490  +
    }
         491  +
         492  +
    fn read_timestamp(&mut self, schema: &Schema) -> Result<DateTime, SerdeError> {
         493  +
        self.skip_whitespace();
         494  +
        let rem = self.remaining();
         495  +
        match rem.first() {
         496  +
            Some(b'"') => {
         497  +
                let s = self.read_string(schema)?;
         498  +
                // Determine parse format from @timestampFormat trait or default
         499  +
                let format = if let Some(ts_trait) = schema.timestamp_format() {
         500  +
                    match ts_trait.format() {
         501  +
                        aws_smithy_schema::traits::TimestampFormat::HttpDate => {
         502  +
                            aws_smithy_types::date_time::Format::HttpDate
         503  +
                        }
         504  +
                        aws_smithy_schema::traits::TimestampFormat::EpochSeconds => {
         505  +
                            aws_smithy_types::date_time::Format::EpochSeconds
         506  +
                        }
         507  +
                        aws_smithy_schema::traits::TimestampFormat::DateTime => {
         508  +
                            aws_smithy_types::date_time::Format::DateTimeWithOffset
         509  +
                        }
         510  +
                    }
         511  +
                } else {
         512  +
                    // Default: try date-time with offsets allowed
         513  +
                    aws_smithy_types::date_time::Format::DateTimeWithOffset
         514  +
                };
         515  +
                DateTime::from_str(&s, format)
         516  +
                    .map_err(|e| SerdeError::custom(format!("invalid timestamp string: {e}")))
         517  +
            }
         518  +
            Some(b'-') | Some(b'0'..=b'9') => {
         519  +
                // Numeric timestamp — epoch seconds
         520  +
                let start = self.position;
  344    521   
                self.consume_number();
         522  +
                let num_str =
         523  +
                    std::str::from_utf8(&self.input[start..self.position]).map_err(|e| {
         524  +
                        SerdeError::InvalidInput {
         525  +
                            message: e.to_string(),
         526  +
                        }
         527  +
                    })?;
         528  +
                if num_str.contains('.') || num_str.contains('e') || num_str.contains('E') {
         529  +
                    let f: f64 = num_str.parse().map_err(|e: std::num::ParseFloatError| {
         530  +
                        SerdeError::InvalidInput {
         531  +
                            message: e.to_string(),
         532  +
                        }
         533  +
                    })?;
         534  +
                    Ok(DateTime::from_secs_f64(f))
         535  +
                } else if num_str.starts_with('-') {
         536  +
                    let n: i64 = num_str.parse().map_err(|e: std::num::ParseIntError| {
         537  +
                        SerdeError::InvalidInput {
         538  +
                            message: e.to_string(),
         539  +
                        }
         540  +
                    })?;
  345    541   
                    Ok(DateTime::from_secs(n))
         542  +
                } else {
         543  +
                    let n: u64 = num_str.parse().map_err(|e: std::num::ParseIntError| {
         544  +
                        SerdeError::InvalidInput {
         545  +
                            message: e.to_string(),
         546  +
                        }
         547  +
                    })?;
         548  +
                    Ok(DateTime::from_secs(n as i64))
         549  +
                }
  346    550   
            }
  347    551   
            _ => Err(SerdeError::TypeMismatch {
  348    552   
                message: "expected timestamp".into(),
  349    553   
            }),
  350    554   
        }
  351    555   
    }
  352    556   
  353    557   
    fn read_document(&mut self, _schema: &Schema) -> Result<Document, SerdeError> {
  354         -
        let mut iter = json_token_iter(self.remaining());
  355         -
        match iter.next() {
  356         -
            Some(Ok(Token::ValueNull { .. })) => {
         558  +
        self.skip_whitespace();
         559  +
        match self.remaining().first() {
         560  +
            Some(b'"') => Ok(Document::String(self.read_string(_schema)?)),
         561  +
            Some(b't') | Some(b'f') => Ok(Document::Bool(self.read_boolean(_schema)?)),
         562  +
            Some(b'n') => {
         563  +
                if self.remaining().starts_with(b"null") {
  357    564   
                    self.advance_by(4);
  358    565   
                    Ok(Document::Null)
         566  +
                } else {
         567  +
                    Err(SerdeError::InvalidInput {
         568  +
                        message: "unexpected token in document".into(),
         569  +
                    })
  359    570   
                }
  360         -
            _ => Err(SerdeError::UnsupportedOperation {
  361         -
                message: "document deserialization not fully implemented".into(),
         571  +
            }
         572  +
            Some(b'{') => {
         573  +
                self.advance_by(1);
         574  +
                let mut map = std::collections::HashMap::new();
         575  +
                loop {
         576  +
                    self.skip_whitespace();
         577  +
                    if self.remaining().first() == Some(&b'}') {
         578  +
                        self.advance_by(1);
         579  +
                        break;
         580  +
                    }
         581  +
                    if self.remaining().first() != Some(&b'"') {
         582  +
                        return Err(SerdeError::InvalidInput {
         583  +
                            message: "expected object key in document".into(),
         584  +
                        });
         585  +
                    }
         586  +
                    let key = self.parse_key()?.into_owned();
         587  +
                    self.skip_whitespace();
         588  +
                    if self.remaining().first() != Some(&b':') {
         589  +
                        return Err(SerdeError::InvalidInput {
         590  +
                            message: "expected colon in document object".into(),
         591  +
                        });
         592  +
                    }
         593  +
                    self.advance_by(1);
         594  +
                    let value = self.read_document(_schema)?;
         595  +
                    map.insert(key, value);
         596  +
                }
         597  +
                Ok(Document::Object(map))
         598  +
            }
         599  +
            Some(b'[') => {
         600  +
                self.advance_by(1);
         601  +
                let mut arr = Vec::new();
         602  +
                loop {
         603  +
                    self.skip_whitespace();
         604  +
                    if self.remaining().first() == Some(&b']') {
         605  +
                        self.advance_by(1);
         606  +
                        break;
         607  +
                    }
         608  +
                    arr.push(self.read_document(_schema)?);
         609  +
                }
         610  +
                Ok(Document::Array(arr))
         611  +
            }
         612  +
            Some(c) if *c == b'-' || c.is_ascii_digit() => {
         613  +
                // Parse number — determine if integer or float
         614  +
                let rem = self.remaining();
         615  +
                let mut len = 0;
         616  +
                let mut is_float = false;
         617  +
                let mut is_negative = false;
         618  +
                for (i, &b) in rem.iter().enumerate() {
         619  +
                    if b == b'-' && i == 0 {
         620  +
                        is_negative = true;
         621  +
                        len += 1;
         622  +
                    } else if b.is_ascii_digit() || b == b'+' {
         623  +
                        len += 1;
         624  +
                    } else if b == b'.' || b == b'e' || b == b'E' {
         625  +
                        is_float = true;
         626  +
                        len += 1;
         627  +
                    } else {
         628  +
                        break;
         629  +
                    }
         630  +
                }
         631  +
                let pos = self.position;
         632  +
                self.advance_by(len);
         633  +
                let s = std::str::from_utf8(&self.input[pos..pos + len]).map_err(|e| {
         634  +
                    SerdeError::InvalidInput {
         635  +
                        message: e.to_string(),
         636  +
                    }
         637  +
                })?;
         638  +
                if is_float {
         639  +
                    let f = s.parse::<f64>().map_err(|e| SerdeError::InvalidInput {
         640  +
                        message: e.to_string(),
         641  +
                    })?;
         642  +
                    Ok(Document::Number(aws_smithy_types::Number::Float(f)))
         643  +
                } else if is_negative {
         644  +
                    let n = s.parse::<i64>().map_err(|e| SerdeError::InvalidInput {
         645  +
                        message: e.to_string(),
         646  +
                    })?;
         647  +
                    Ok(Document::Number(aws_smithy_types::Number::NegInt(n)))
         648  +
                } else {
         649  +
                    let n = s.parse::<u64>().map_err(|e| SerdeError::InvalidInput {
         650  +
                        message: e.to_string(),
         651  +
                    })?;
         652  +
                    Ok(Document::Number(aws_smithy_types::Number::PosInt(n)))
         653  +
                }
         654  +
            }
         655  +
            _ => Err(SerdeError::InvalidInput {
         656  +
                message: "unexpected token in document".into(),
  362    657   
            }),
  363    658   
        }
  364    659   
    }
  365    660   
  366    661   
    fn is_null(&self) -> bool {
  367         -
        let mut iter = json_token_iter(self.remaining());
  368         -
        matches!(iter.next(), Some(Ok(Token::ValueNull { .. })))
         662  +
        let remaining = self.remaining();
         663  +
        remaining.len() >= 4
         664  +
            && &remaining[..4] == b"null"
         665  +
            && !remaining.get(4).is_some_and(|b| b.is_ascii_alphanumeric())
         666  +
    }
         667  +
         668  +
    fn read_null(&mut self) -> Result<(), SerdeError> {
         669  +
        self.skip_whitespace();
         670  +
        if self.is_null() {
         671  +
            self.advance_by(4);
         672  +
        }
         673  +
        Ok(())
  369    674   
    }
  370    675   
  371    676   
    fn container_size(&self) -> Option<usize> {
  372    677   
        let mut iter = json_token_iter(self.remaining());
  373    678   
        match iter.next()? {
  374    679   
            Ok(Token::StartArray { .. }) => {
  375    680   
                let mut count = 0;
  376    681   
                let mut depth = 1;
  377    682   
                for token in iter {
  378    683   
                    match token {
@@ -420,725 +586,932 @@
  440    745   
            if b.is_ascii_digit() || b == b'-' || b == b'.' || b == b'e' || b == b'E' || b == b'+' {
  441    746   
                len += 1;
  442    747   
            } else {
  443    748   
                break;
  444    749   
            }
  445    750   
        }
  446    751   
        self.advance_by(len);
  447    752   
    }
  448    753   
  449    754   
    fn skip_value(&mut self) -> Result<(), SerdeError> {
  450         -
        let mut depth = 0;
         755  +
        self.skip_whitespace();
         756  +
        let mut depth: usize = 0;
  451    757   
        loop {
  452         -
            let mut iter = json_token_iter(self.remaining());
  453         -
            match iter.next() {
  454         -
                Some(Ok(Token::StartObject { .. })) | Some(Ok(Token::StartArray { .. })) => {
         758  +
            self.skip_whitespace();
         759  +
            match self.remaining().first().copied() {
         760  +
                Some(b'{') | Some(b'[') => {
  455    761   
                    self.advance_by(1);
  456    762   
                    depth += 1;
  457    763   
                }
  458         -
                Some(Ok(Token::EndObject { .. })) | Some(Ok(Token::EndArray { .. })) => {
  459         -
                    self.advance_by(1);
         764  +
                Some(b'}') | Some(b']') => {
  460    765   
                    if depth == 0 {
  461    766   
                        return Err(SerdeError::InvalidInput {
  462    767   
                            message: "unexpected end token".into(),
  463    768   
                        });
  464    769   
                    }
         770  +
                    self.advance_by(1);
  465    771   
                    depth -= 1;
  466    772   
                    if depth == 0 {
  467    773   
                        return Ok(());
  468    774   
                    }
  469    775   
                }
  470         -
                Some(Ok(Token::ValueBool { value, .. })) if depth == 0 => {
  471         -
                    self.advance_by(if value { 4 } else { 5 });
         776  +
                Some(b'"') => {
         777  +
                    // Skip quoted string (handles escapes)
         778  +
                    let mut i = 1;
         779  +
                    let rem = self.remaining();
         780  +
                    while i < rem.len() {
         781  +
                        if rem[i] == b'\\' {
         782  +
                            i += 2; // skip escape sequence
         783  +
                        } else if rem[i] == b'"' {
         784  +
                            i += 1;
         785  +
                            break;
         786  +
                        } else {
         787  +
                            i += 1;
         788  +
                        }
         789  +
                    }
         790  +
                    self.advance_by(i);
         791  +
                    // After a string inside an object, skip optional ':'
         792  +
                    if depth > 0 {
         793  +
                        self.skip_whitespace();
         794  +
                        if self.remaining().first() == Some(&b':') {
         795  +
                            self.advance_by(1);
         796  +
                            continue; // read the value after the colon
         797  +
                        }
         798  +
                    }
         799  +
                    if depth == 0 {
  472    800   
                        return Ok(());
  473    801   
                    }
  474         -
                Some(Ok(Token::ValueNull { .. })) if depth == 0 => {
  475         -
                    self.advance_by(4);
         802  +
                }
         803  +
                Some(b't') => {
         804  +
                    self.advance_by(4); // true
         805  +
                    if depth == 0 {
  476    806   
                        return Ok(());
  477    807   
                    }
  478         -
                Some(Ok(Token::ValueString { value, .. })) if depth == 0 => {
  479         -
                    self.advance_by(value.as_escaped_str().len() + 2);
         808  +
                }
         809  +
                Some(b'f') => {
         810  +
                    self.advance_by(5); // false
         811  +
                    if depth == 0 {
  480    812   
                        return Ok(());
  481    813   
                    }
  482         -
                Some(Ok(Token::ValueNumber { .. })) if depth == 0 => {
         814  +
                }
         815  +
                Some(b'n') => {
         816  +
                    self.advance_by(4); // null
         817  +
                    if depth == 0 {
         818  +
                        return Ok(());
         819  +
                    }
         820  +
                }
         821  +
                Some(c) if c == b'-' || c.is_ascii_digit() => {
  483    822   
                    self.consume_number();
         823  +
                    if depth == 0 {
  484    824   
                        return Ok(());
  485    825   
                    }
  486         -
                Some(Ok(Token::ObjectKey { key, .. })) => {
  487         -
                    self.advance_by(key.as_escaped_str().len() + 3);
  488    826   
                }
  489         -
                Some(Ok(_)) => {}
  490         -
                Some(Err(e)) => {
         827  +
                Some(_) => {
  491    828   
                    return Err(SerdeError::InvalidInput {
  492         -
                        message: e.to_string(),
         829  +
                        message: "unexpected token in skip_value".into(),
  493    830   
                    })
  494    831   
                }
  495    832   
                None => {
  496    833   
                    return Err(SerdeError::InvalidInput {
  497    834   
                        message: "unexpected end of input".into(),
  498    835   
                    })
  499    836   
                }
  500    837   
            }
  501    838   
        }
  502    839   
    }
  503    840   
  504    841   
    fn read_integer_value(&mut self) -> Result<i64, SerdeError> {
  505         -
        let mut iter = json_token_iter(self.remaining());
  506         -
        match iter.next() {
  507         -
            Some(Ok(Token::ValueNumber {
  508         -
                value: Number::PosInt(n),
  509         -
                ..
  510         -
            })) => {
  511         -
                self.consume_number();
  512         -
                i64::try_from(n).map_err(|_| SerdeError::InvalidInput {
  513         -
                    message: "value out of range".into(),
  514         -
                })
         842  +
        self.skip_whitespace();
         843  +
        let rem = self.remaining();
         844  +
        let mut len = 0;
         845  +
        for &b in rem {
         846  +
            if b.is_ascii_digit() || b == b'-' || b == b'+' {
         847  +
                len += 1;
         848  +
            } else {
         849  +
                break;
  515    850   
            }
  516         -
            Some(Ok(Token::ValueNumber {
  517         -
                value: Number::NegInt(n),
  518         -
                ..
  519         -
            })) => {
  520         -
                self.consume_number();
  521         -
                Ok(n)
  522    851   
        }
  523         -
            _ => Err(SerdeError::TypeMismatch {
         852  +
        if len == 0 {
         853  +
            return Err(SerdeError::TypeMismatch {
  524    854   
                message: "expected integer".into(),
  525         -
            }),
         855  +
            });
  526    856   
        }
         857  +
        let s = std::str::from_utf8(&rem[..len]).map_err(|e| SerdeError::InvalidInput {
         858  +
            message: e.to_string(),
         859  +
        })?;
         860  +
        let n = s.parse::<i64>().map_err(|e| SerdeError::InvalidInput {
         861  +
            message: e.to_string(),
         862  +
        })?;
         863  +
        self.advance_by(len);
         864  +
        Ok(n)
  527    865   
    }
  528    866   
  529    867   
    fn read_float_value(&mut self) -> Result<f64, SerdeError> {
  530         -
        let mut iter = json_token_iter(self.remaining());
  531         -
        match iter.next() {
  532         -
            Some(Ok(Token::ValueNumber {
  533         -
                value: Number::Float(f),
  534         -
                ..
  535         -
            })) => {
  536         -
                self.consume_number();
  537         -
                Ok(f)
         868  +
        self.skip_whitespace();
         869  +
        let rem = self.remaining();
         870  +
        // Handle string-encoded special float values: "NaN", "Infinity", "-Infinity"
         871  +
        if rem.first() == Some(&b'"') {
         872  +
            let s = self.read_string(&aws_smithy_schema::prelude::STRING)?;
         873  +
            return match s.as_str() {
         874  +
                "NaN" => Ok(f64::NAN),
         875  +
                "Infinity" => Ok(f64::INFINITY),
         876  +
                "-Infinity" => Ok(f64::NEG_INFINITY),
         877  +
                _ => s.parse::<f64>().map_err(|e| SerdeError::InvalidInput {
         878  +
                    message: e.to_string(),
         879  +
                }),
         880  +
            };
  538    881   
        }
  539         -
            Some(Ok(Token::ValueNumber {
  540         -
                value: Number::PosInt(n),
  541         -
                ..
  542         -
            })) => {
  543         -
                self.consume_number();
  544         -
                Ok(n as f64)
         882  +
        let mut len = 0;
         883  +
        for &b in rem {
         884  +
            if b.is_ascii_digit() || b == b'-' || b == b'+' || b == b'.' || b == b'e' || b == b'E' {
         885  +
                len += 1;
         886  +
            } else {
         887  +
                break;
  545    888   
            }
  546         -
            Some(Ok(Token::ValueNumber {
  547         -
                value: Number::NegInt(n),
  548         -
                ..
  549         -
            })) => {
  550         -
                self.consume_number();
  551         -
                Ok(n as f64)
  552    889   
        }
  553         -
            _ => Err(SerdeError::TypeMismatch {
         890  +
        if len == 0 {
         891  +
            return Err(SerdeError::TypeMismatch {
  554    892   
                message: "expected number".into(),
  555         -
            }),
         893  +
            });
  556    894   
        }
         895  +
        let s = std::str::from_utf8(&rem[..len]).map_err(|e| SerdeError::InvalidInput {
         896  +
            message: e.to_string(),
         897  +
        })?;
         898  +
        let n = s.parse::<f64>().map_err(|e| SerdeError::InvalidInput {
         899  +
            message: e.to_string(),
         900  +
        })?;
         901  +
        self.advance_by(len);
         902  +
        Ok(n)
  557    903   
    }
  558    904   
}
  559    905   
  560    906   
#[cfg(test)]
  561    907   
mod tests {
  562    908   
    use super::*;
  563    909   
  564    910   
    fn dummy_schema() -> &'static aws_smithy_schema::Schema {
  565    911   
        &aws_smithy_schema::prelude::STRING
  566    912   
    }
@@ -642,988 +866,1218 @@
  662   1008   
            "age",
  663   1009   
            2,
  664   1010   
        );
  665   1011   
        static PERSON_SCHEMA: Schema = Schema::new_struct(
  666   1012   
            aws_smithy_schema::shape_id!("test", "Person"),
  667   1013   
            aws_smithy_schema::ShapeType::Structure,
  668   1014   
            &[&FIRST_NAME, &LAST_NAME, &AGE],
  669   1015   
        );
  670   1016   
  671   1017   
        fn consume_person(
  672         -
            mut person: Person,
        1018  +
            person: &mut Person,
  673   1019   
            schema: &Schema,
  674         -
            deser: &mut JsonDeserializer,
  675         -
        ) -> Result<Person, SerdeError> {
        1020  +
            deser: &mut dyn ShapeDeserializer,
        1021  +
        ) -> Result<(), SerdeError> {
  676   1022   
            match schema.member_name() {
  677   1023   
                Some("firstName") => person.first_name = deser.read_string(schema)?,
  678   1024   
                Some("lastName") => person.last_name = deser.read_string(schema)?,
  679   1025   
                Some("age") => person.age = deser.read_integer(schema)?,
  680   1026   
                _ => {}
  681   1027   
            }
  682         -
            Ok(person)
        1028  +
            Ok(())
  683   1029   
        }
  684   1030   
  685   1031   
        let json = br#"{"lastName":"Smithy","firstName":"Alice","age":30}"#;
  686   1032   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  687         -
        let person = deser
  688         -
            .read_struct(&PERSON_SCHEMA, Person::default(), consume_person)
        1033  +
        let mut person = Person::default();
        1034  +
        deser
        1035  +
            .read_struct(&PERSON_SCHEMA, &mut |member, d| {
        1036  +
                consume_person(&mut person, member, d)
        1037  +
            })
  689   1038   
            .unwrap();
  690   1039   
        assert_eq!(
  691   1040   
            person,
  692   1041   
            Person {
  693   1042   
                first_name: "Alice".to_string(),
  694   1043   
                last_name: "Smithy".to_string(),
  695   1044   
                age: 30
  696   1045   
            }
  697   1046   
        );
  698   1047   
  699   1048   
        let json =
  700   1049   
            br#"{"firstName":          "Alice","age":12345678,     "lastName":"\"Smithy\""}"#;
  701   1050   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  702         -
        let person = deser
  703         -
            .read_struct(&PERSON_SCHEMA, Person::default(), consume_person)
        1051  +
        let mut person = Person::default();
        1052  +
        deser
        1053  +
            .read_struct(&PERSON_SCHEMA, &mut |member, d| {
        1054  +
                consume_person(&mut person, member, d)
        1055  +
            })
  704   1056   
            .unwrap();
  705   1057   
        assert_eq!(
  706   1058   
            person,
  707   1059   
            Person {
  708   1060   
                first_name: "Alice".to_string(),
  709   1061   
                last_name: "\"Smithy\"".to_string(),
  710   1062   
                age: 12345678
  711   1063   
            }
  712   1064   
        );
  713   1065   
    }
  714   1066   
  715   1067   
    #[test]
  716   1068   
    fn test_read_list() {
  717   1069   
        let json = b"[1, 2, 3, 4, 5]";
  718   1070   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  719   1071   
        let capacity = deser.container_size().unwrap_or(0);
  720         -
        let container = Vec::with_capacity(capacity);
  721         -
        let allocated_capacity = container.capacity();
  722         -
        let result = deser
  723         -
            .read_list(dummy_schema(), container, |mut vec, deser| {
  724         -
                vec.push(deser.read_integer(dummy_schema())?);
  725         -
                Ok(vec)
        1072  +
        let mut result = Vec::with_capacity(capacity);
        1073  +
        let allocated_capacity = result.capacity();
        1074  +
        deser
        1075  +
            .read_list(dummy_schema(), &mut |deser| {
        1076  +
                result.push(deser.read_integer(dummy_schema())?);
        1077  +
                Ok(())
  726   1078   
            })
  727   1079   
            .unwrap();
  728   1080   
        assert_eq!(result, vec![1, 2, 3, 4, 5]);
  729   1081   
        // Ensure no more memory was allocated for the container
  730   1082   
        assert_eq!(result.capacity(), allocated_capacity);
  731   1083   
  732   1084   
        let json = b"[]";
  733   1085   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  734   1086   
        let capacity = deser.container_size().unwrap_or(0);
  735         -
        let container = Vec::with_capacity(capacity);
  736         -
        let allocated_capacity = container.capacity();
  737         -
        let result = deser
  738         -
            .read_list(dummy_schema(), container, |mut vec, deser| {
  739         -
                vec.push(deser.read_integer(dummy_schema())?);
  740         -
                Ok(vec)
        1087  +
        let mut result = Vec::<i32>::with_capacity(capacity);
        1088  +
        let allocated_capacity = result.capacity();
        1089  +
        deser
        1090  +
            .read_list(dummy_schema(), &mut |deser| {
        1091  +
                result.push(deser.read_integer(dummy_schema())?);
        1092  +
                Ok(())
  741   1093   
            })
  742   1094   
            .unwrap();
  743   1095   
        assert_eq!(result, Vec::<i32>::new());
  744   1096   
        // Ensure no more memory was allocated for the container
  745   1097   
        assert_eq!(result.capacity(), allocated_capacity);
  746   1098   
  747   1099   
        let json = br#"["hello", "world"]"#;
  748   1100   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  749   1101   
        let capacity = deser.container_size().unwrap_or(0);
  750         -
        let container = Vec::with_capacity(capacity);
  751         -
        let allocated_capacity = container.capacity();
  752         -
        let result = deser
  753         -
            .read_list(dummy_schema(), container, |mut vec, deser| {
  754         -
                vec.push(deser.read_string(dummy_schema())?);
  755         -
                Ok(vec)
        1102  +
        let mut result = Vec::with_capacity(capacity);
        1103  +
        let allocated_capacity = result.capacity();
        1104  +
        deser
        1105  +
            .read_list(dummy_schema(), &mut |deser| {
        1106  +
                result.push(deser.read_string(dummy_schema())?);
        1107  +
                Ok(())
  756   1108   
            })
  757   1109   
            .unwrap();
  758   1110   
        assert_eq!(result, vec!["hello", "world"]);
  759   1111   
        // Ensure no more memory was allocated for the container
  760   1112   
        assert_eq!(result.capacity(), allocated_capacity);
  761   1113   
    }
  762   1114   
  763   1115   
    #[test]
  764   1116   
    fn test_container_size() {
  765   1117   
        let deser =
  766   1118   
            JsonDeserializer::new(b"[1, 2, 3, 4, 5]", Arc::new(JsonCodecSettings::default()));
  767   1119   
        assert_eq!(deser.container_size(), Some(5));
  768   1120   
  769   1121   
        let deser = JsonDeserializer::new(b"[]", Arc::new(JsonCodecSettings::default()));
  770   1122   
        assert_eq!(deser.container_size(), Some(0));
  771   1123   
  772   1124   
        let deser = JsonDeserializer::new(
  773   1125   
            br#"{"a": 1, "b": 2, "c": 3}"#,
  774   1126   
            Arc::new(JsonCodecSettings::default()),
  775   1127   
        );
  776   1128   
        assert_eq!(deser.container_size(), Some(3));
  777   1129   
  778   1130   
        let deser = JsonDeserializer::new(b"{}", Arc::new(JsonCodecSettings::default()));
  779   1131   
        assert_eq!(deser.container_size(), Some(0));
  780   1132   
  781   1133   
        let deser = JsonDeserializer::new(
  782   1134   
            b"[[1, 2], [3, 4], [5, 6]]",
  783   1135   
            Arc::new(JsonCodecSettings::default()),
  784   1136   
        );
  785   1137   
        assert_eq!(deser.container_size(), Some(3));
  786   1138   
  787   1139   
        let deser = JsonDeserializer::new(b"42", Arc::new(JsonCodecSettings::default()));
  788   1140   
        assert_eq!(deser.container_size(), None);
  789   1141   
    }
  790   1142   
  791   1143   
    #[test]
  792   1144   
    fn test_read_map() {
  793   1145   
        use std::collections::HashMap;
  794   1146   
  795   1147   
        let json = br#"{"a": 1, "b": 2, "c": 3}"#;
  796   1148   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  797   1149   
        let calculated_capacity = deser.container_size().unwrap_or(0);
  798         -
        let container = HashMap::with_capacity(calculated_capacity);
  799         -
        let allocated_capacity = container.capacity();
  800         -
        let result = deser
  801         -
            .read_map(dummy_schema(), container, |mut map, key, deser| {
  802         -
                map.insert(key, deser.read_integer(dummy_schema())?);
  803         -
                Ok(map)
        1150  +
        let mut result = HashMap::with_capacity(calculated_capacity);
        1151  +
        let allocated_capacity = result.capacity();
        1152  +
        deser
        1153  +
            .read_map(dummy_schema(), &mut |key, deser| {
        1154  +
                result.insert(key, deser.read_integer(dummy_schema())?);
        1155  +
                Ok(())
  804   1156   
            })
  805   1157   
            .unwrap();
  806   1158   
        assert_eq!(result.len(), 3);
  807   1159   
        assert_eq!(result.get("a"), Some(&1));
  808   1160   
        assert_eq!(result.get("b"), Some(&2));
  809   1161   
        assert_eq!(result.get("c"), Some(&3));
  810   1162   
        // Ensure no more memory was allocated for the container
  811   1163   
        assert_eq!(result.capacity(), allocated_capacity);
  812   1164   
  813   1165   
        let json = b"{}";
  814   1166   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  815   1167   
        let calculated_capacity = deser.container_size().unwrap_or(0);
  816         -
        let container = HashMap::with_capacity(calculated_capacity);
  817         -
        let allocated_capacity = container.capacity();
  818         -
        let result = deser
  819         -
            .read_map(dummy_schema(), container, |mut map, key, deser| {
  820         -
                map.insert(key, deser.read_integer(dummy_schema())?);
  821         -
                Ok(map)
        1168  +
        let mut result = HashMap::<String, i32>::with_capacity(calculated_capacity);
        1169  +
        let allocated_capacity = result.capacity();
        1170  +
        deser
        1171  +
            .read_map(dummy_schema(), &mut |key, deser| {
        1172  +
                result.insert(key, deser.read_integer(dummy_schema())?);
        1173  +
                Ok(())
  822   1174   
            })
  823   1175   
            .unwrap();
  824   1176   
        assert_eq!(result, HashMap::<String, i32>::new());
  825   1177   
        // Ensure no more memory was allocated for the container
  826   1178   
        assert_eq!(result.capacity(), allocated_capacity);
  827   1179   
  828   1180   
        let json = br#"{"name": "Alice", "city": "Seattle"}"#;
  829   1181   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
  830   1182   
        let calculated_capacity = deser.container_size().unwrap_or(0);
  831         -
        let container = HashMap::with_capacity(calculated_capacity);
  832         -
        let allocated_capacity = container.capacity();
  833         -
        let result = deser
  834         -
            .read_map(dummy_schema(), container, |mut map, key, deser| {
  835         -
                map.insert(key, deser.read_string(dummy_schema())?);
  836         -
                Ok(map)
        1183  +
        let mut result = HashMap::with_capacity(calculated_capacity);
        1184  +
        let allocated_capacity = result.capacity();
        1185  +
        deser
        1186  +
            .read_map(dummy_schema(), &mut |key, deser| {
        1187  +
                result.insert(key, deser.read_string(dummy_schema())?);
        1188  +
                Ok(())
  837   1189   
            })
  838   1190   
            .unwrap();
  839   1191   
        assert_eq!(result.len(), 2);
  840   1192   
        assert_eq!(result.get("name"), Some(&"Alice".to_string()));
  841   1193   
        assert_eq!(result.get("city"), Some(&"Seattle".to_string()));
  842   1194   
        // Ensure no more memory was allocated for the container
  843   1195   
        assert_eq!(result.capacity(), allocated_capacity);
  844   1196   
    }
  845   1197   
  846   1198   
    #[test]
@@ -951,1303 +1170,1651 @@
  971   1323   
                &USER_ID,
  972   1324   
                &USER_NAME,
  973   1325   
                &USER_SCORES,
  974   1326   
                &USER_ADDRESS,
  975   1327   
                &USER_COMPANIES,
  976   1328   
                &USER_TAGS,
  977   1329   
            ],
  978   1330   
        );
  979   1331   
  980   1332   
        fn consume_address(
  981         -
            mut addr: Address,
        1333  +
            addr: &mut Address,
  982   1334   
            schema: &Schema,
  983         -
            deser: &mut JsonDeserializer,
  984         -
        ) -> Result<Address, SerdeError> {
        1335  +
            deser: &mut dyn ShapeDeserializer,
        1336  +
        ) -> Result<(), SerdeError> {
  985   1337   
            match schema.member_name() {
  986   1338   
                Some("street") => addr.street = deser.read_string(schema)?,
  987   1339   
                Some("city") => addr.city = deser.read_string(schema)?,
  988   1340   
                Some("zip") => addr.zip = deser.read_integer(schema)?,
  989   1341   
                _ => {}
  990   1342   
            }
  991         -
            Ok(addr)
        1343  +
            Ok(())
  992   1344   
        }
  993   1345   
  994   1346   
        fn consume_company(
  995         -
            mut comp: Company,
        1347  +
            comp: &mut Company,
  996   1348   
            schema: &Schema,
  997         -
            deser: &mut JsonDeserializer,
  998         -
        ) -> Result<Company, SerdeError> {
        1349  +
            deser: &mut dyn ShapeDeserializer,
        1350  +
        ) -> Result<(), SerdeError> {
  999   1351   
            match schema.member_name() {
 1000   1352   
                Some("name") => comp.name = deser.read_string(schema)?,
 1001   1353   
                Some("active") => comp.active = deser.read_boolean(schema)?,
 1002   1354   
                Some("employees") => {
 1003         -
                    comp.employees = deser.read_list(schema, Vec::new(), |mut v, d| {
        1355  +
                    let mut v = Vec::new();
        1356  +
                    deser.read_list(schema, &mut |d| {
 1004   1357   
                        v.push(d.read_string(dummy_schema())?);
 1005         -
                        Ok(v)
 1006         -
                    })?
        1358  +
                        Ok(())
        1359  +
                    })?;
        1360  +
                    comp.employees = v;
 1007   1361   
                }
 1008   1362   
                Some("metadata") => {
 1009         -
                    comp.metadata = deser.read_map(schema, HashMap::new(), |mut m, k, d| {
        1363  +
                    let mut m = HashMap::new();
        1364  +
                    deser.read_map(schema, &mut |k, d| {
 1010   1365   
                        m.insert(k, d.read_integer(dummy_schema())?);
 1011         -
                        Ok(m)
 1012         -
                    })?
        1366  +
                        Ok(())
        1367  +
                    })?;
        1368  +
                    comp.metadata = m;
 1013   1369   
                }
 1014   1370   
                _ => {}
 1015   1371   
            }
 1016         -
            Ok(comp)
        1372  +
            Ok(())
 1017   1373   
        }
 1018   1374   
 1019   1375   
        fn consume_user(
 1020         -
            mut user: User,
        1376  +
            user: &mut User,
 1021   1377   
            schema: &Schema,
 1022         -
            deser: &mut JsonDeserializer,
 1023         -
        ) -> Result<User, SerdeError> {
        1378  +
            deser: &mut dyn ShapeDeserializer,
        1379  +
        ) -> Result<(), SerdeError> {
 1024   1380   
            match schema.member_name() {
 1025   1381   
                Some("id") => user.id = deser.read_long(schema)?,
 1026   1382   
                Some("name") => user.name = deser.read_string(schema)?,
 1027   1383   
                Some("scores") => {
 1028         -
                    user.scores = deser.read_list(schema, Vec::new(), |mut v, d| {
        1384  +
                    let mut v = Vec::new();
        1385  +
                    deser.read_list(schema, &mut |d| {
 1029   1386   
                        v.push(d.read_double(dummy_schema())?);
 1030         -
                        Ok(v)
 1031         -
                    })?
        1387  +
                        Ok(())
        1388  +
                    })?;
        1389  +
                    user.scores = v;
 1032   1390   
                }
 1033   1391   
                Some("address") => {
 1034         -
                    user.address =
 1035         -
                        deser.read_struct(&ADDRESS_SCHEMA, Address::default(), consume_address)?
        1392  +
                    let mut addr = Address::default();
        1393  +
                    deser.read_struct(&ADDRESS_SCHEMA, &mut |member, d| {
        1394  +
                        consume_address(&mut addr, member, d)
        1395  +
                    })?;
        1396  +
                    user.address = addr;
 1036   1397   
                }
 1037   1398   
                Some("companies") => {
 1038         -
                    user.companies = deser.read_list(schema, Vec::new(), |mut v, d| {
 1039         -
                        v.push(d.read_struct(
 1040         -
                            &COMPANY_SCHEMA,
 1041         -
                            Company::default(),
 1042         -
                            consume_company,
 1043         -
                        )?);
 1044         -
                        Ok(v)
 1045         -
                    })?
        1399  +
                    let mut v = Vec::new();
        1400  +
                    deser.read_list(schema, &mut |d| {
        1401  +
                        let mut comp = Company::default();
        1402  +
                        d.read_struct(&COMPANY_SCHEMA, &mut |member, d| {
        1403  +
                            consume_company(&mut comp, member, d)
        1404  +
                        })?;
        1405  +
                        v.push(comp);
        1406  +
                        Ok(())
        1407  +
                    })?;
        1408  +
                    user.companies = v;
 1046   1409   
                }
 1047   1410   
                Some("tags") => {
 1048         -
                    user.tags = deser.read_map(schema, HashMap::new(), |mut m, k, d| {
        1411  +
                    let mut m = HashMap::new();
        1412  +
                    deser.read_map(schema, &mut |k, d| {
 1049   1413   
                        m.insert(k, d.read_string(dummy_schema())?);
 1050         -
                        Ok(m)
 1051         -
                    })?
        1414  +
                        Ok(())
        1415  +
                    })?;
        1416  +
                    user.tags = m;
 1052   1417   
                }
 1053   1418   
                _ => {}
 1054   1419   
            }
 1055         -
            Ok(user)
        1420  +
            Ok(())
 1056   1421   
        }
 1057   1422   
 1058   1423   
        let json = br#"{
 1059   1424   
            "id": 12345,
 1060   1425   
            "name": "John Doe",
 1061   1426   
            "scores": [95.5, 87.3, 92.1],
 1062   1427   
            "address": {
 1063   1428   
                "street": "123 Main St",
 1064   1429   
                "city": "Seattle",
 1065   1430   
                "zip": 98101
 1066   1431   
            },
 1067   1432   
            "companies": [
 1068   1433   
                {
 1069   1434   
                    "name": "TechCorp",
 1070   1435   
                    "employees": ["Alice", "Bob"],
 1071   1436   
                    "metadata": {"founded": 2010, "size": 500},
 1072   1437   
                    "active": true
 1073   1438   
                },
 1074   1439   
                {
 1075   1440   
                    "name": "StartupInc",
 1076   1441   
                    "employees": ["Charlie"],
 1077   1442   
                    "metadata": {"founded": 2020},
 1078   1443   
                    "active": false
 1079   1444   
                }
 1080   1445   
            ],
 1081   1446   
            "tags": {"role": "admin", "level": "senior"}
 1082   1447   
        }"#;
 1083   1448   
 1084   1449   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
 1085         -
        let user = deser
 1086         -
            .read_struct(&USER_SCHEMA, User::default(), consume_user)
        1450  +
        let mut user = User::default();
        1451  +
        deser
        1452  +
            .read_struct(&USER_SCHEMA, &mut |member, d| {
        1453  +
                consume_user(&mut user, member, d)
        1454  +
            })
 1087   1455   
            .unwrap();
 1088   1456   
 1089   1457   
        assert_eq!(user.id, 12345);
 1090   1458   
        assert_eq!(user.name, "John Doe");
 1091   1459   
        assert_eq!(user.scores, vec![95.5, 87.3, 92.1]);
 1092   1460   
        assert_eq!(user.address.street, "123 Main St");
 1093   1461   
        assert_eq!(user.address.city, "Seattle");
 1094   1462   
        assert_eq!(user.address.zip, 98101);
 1095   1463   
        assert_eq!(user.companies.len(), 2);
 1096   1464   
        assert_eq!(user.companies[0].name, "TechCorp");
 1097   1465   
        assert_eq!(user.companies[0].employees, vec!["Alice", "Bob"]);
 1098   1466   
        assert_eq!(user.companies[0].metadata.get("founded"), Some(&2010));
 1099   1467   
        assert_eq!(user.companies[0].metadata.get("size"), Some(&500));
 1100   1468   
        assert!(user.companies[0].active);
 1101   1469   
        assert_eq!(user.companies[1].name, "StartupInc");
 1102   1470   
        assert_eq!(user.companies[1].employees, vec!["Charlie"]);
 1103   1471   
        assert_eq!(user.companies[1].metadata.get("founded"), Some(&2020));
 1104   1472   
        assert!(!user.companies[1].active);
 1105   1473   
        assert_eq!(user.tags.get("role"), Some(&"admin".to_string()));
 1106   1474   
        assert_eq!(user.tags.get("level"), Some(&"senior".to_string()));
 1107   1475   
    }
 1108   1476   
 1109   1477   
    #[test]
 1110   1478   
    fn test_json_name_deserialization() {
 1111   1479   
        use aws_smithy_schema::Schema;
 1112   1480   
 1113   1481   
        static FOO_MEMBER: Schema = Schema::new_member(
 1114   1482   
            aws_smithy_schema::shape_id!("test", "MyStruct"),
 1115   1483   
            aws_smithy_schema::ShapeType::String,
 1116   1484   
            "foo",
 1117   1485   
            0,
 1118   1486   
        );
 1119   1487   
        // "bar" member has @jsonName("Baz")
 1120   1488   
        static BAR_MEMBER: Schema = Schema::new_member(
 1121   1489   
            aws_smithy_schema::shape_id!("test", "MyStruct"),
 1122   1490   
            aws_smithy_schema::ShapeType::Integer,
 1123   1491   
            "bar",
 1124   1492   
            1,
 1125   1493   
        )
 1126   1494   
        .with_json_name("Baz");
 1127   1495   
        static STRUCT_SCHEMA: Schema = Schema::new_struct(
 1128   1496   
            aws_smithy_schema::shape_id!("test", "MyStruct"),
 1129   1497   
            aws_smithy_schema::ShapeType::Structure,
 1130   1498   
            &[&FOO_MEMBER, &BAR_MEMBER],
 1131   1499   
        );
 1132   1500   
 1133   1501   
        let json = br#"{"foo":"hello","Baz":42}"#;
 1134   1502   
 1135   1503   
        // With use_json_name=true, "Baz" resolves to the "bar" member
 1136   1504   
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
 1137   1505   
        let (mut foo, mut bar) = (None::<String>, None::<i32>);
 1138   1506   
        deser
 1139         -
            .read_struct(&STRUCT_SCHEMA, (), |_, member, d| {
        1507  +
            .read_struct(&STRUCT_SCHEMA, &mut |member, d| {
 1140   1508   
                match member.member_name() {
 1141   1509   
                    Some("foo") => foo = Some(d.read_string(member)?),
 1142   1510   
                    Some("bar") => bar = Some(d.read_integer(member)?),
 1143   1511   
                    _ => {}
 1144   1512   
                }
 1145   1513   
                Ok(())
 1146   1514   
            })
 1147   1515   
            .unwrap();
 1148   1516   
        assert_eq!(foo.as_deref(), Some("hello"));
 1149   1517   
        assert_eq!(bar, Some(42));
 1150   1518   
 1151   1519   
        // With use_json_name=false, "Baz" is unknown and gets skipped
 1152   1520   
        let mut deser = JsonDeserializer::new(
 1153   1521   
            json,
 1154   1522   
            Arc::new(JsonCodecSettings::builder().use_json_name(false).build()),
 1155   1523   
        );
 1156   1524   
        let (mut foo, mut bar) = (None::<String>, None::<i32>);
 1157   1525   
        deser
 1158         -
            .read_struct(&STRUCT_SCHEMA, (), |_, member, d| {
        1526  +
            .read_struct(&STRUCT_SCHEMA, &mut |member, d| {
 1159   1527   
                match member.member_name() {
 1160   1528   
                    Some("foo") => foo = Some(d.read_string(member)?),
 1161   1529   
                    Some("bar") => bar = Some(d.read_integer(member)?),
 1162   1530   
                    _ => {}
 1163   1531   
                }
 1164   1532   
                Ok(())
 1165   1533   
            })
 1166   1534   
            .unwrap();
 1167   1535   
        assert_eq!(foo.as_deref(), Some("hello"));
 1168   1536   
        assert_eq!(bar, None); // "Baz" not recognized without jsonName
 1169   1537   
    }
        1538  +
        1539  +
    fn timestamp_schema() -> &'static aws_smithy_schema::Schema {
        1540  +
        &aws_smithy_schema::prelude::TIMESTAMP
        1541  +
    }
        1542  +
        1543  +
    #[test]
        1544  +
    fn test_read_timestamp_positive_integer() {
        1545  +
        let mut deser =
        1546  +
            JsonDeserializer::new(b"1700000000", Arc::new(JsonCodecSettings::default()));
        1547  +
        let ts = deser.read_timestamp(timestamp_schema()).unwrap();
        1548  +
        assert_eq!(ts, DateTime::from_secs(1700000000));
        1549  +
    }
        1550  +
        1551  +
    #[test]
        1552  +
    fn test_read_timestamp_negative_integer() {
        1553  +
        let mut deser = JsonDeserializer::new(b"-1000", Arc::new(JsonCodecSettings::default()));
        1554  +
        let ts = deser.read_timestamp(timestamp_schema()).unwrap();
        1555  +
        assert_eq!(ts, DateTime::from_secs(-1000));
        1556  +
    }
        1557  +
        1558  +
    #[test]
        1559  +
    fn test_read_timestamp_float() {
        1560  +
        // This is the format DynamoDB uses: epoch seconds with fractional part
        1561  +
        let mut deser =
        1562  +
            JsonDeserializer::new(b"1.615218678973E9", Arc::new(JsonCodecSettings::default()));
        1563  +
        let ts = deser.read_timestamp(timestamp_schema()).unwrap();
        1564  +
        assert_eq!(ts, DateTime::from_secs_f64(1.615218678973E9));
        1565  +
    }
        1566  +
        1567  +
    #[test]
        1568  +
    fn test_read_timestamp_float_simple() {
        1569  +
        let mut deser =
        1570  +
            JsonDeserializer::new(b"1700000000.5", Arc::new(JsonCodecSettings::default()));
        1571  +
        let ts = deser.read_timestamp(timestamp_schema()).unwrap();
        1572  +
        assert_eq!(ts, DateTime::from_secs_f64(1700000000.5));
        1573  +
    }
        1574  +
        1575  +
    #[test]
        1576  +
    fn test_read_timestamp_string_datetime() {
        1577  +
        let mut deser = JsonDeserializer::new(
        1578  +
            br#""2023-11-14T22:13:20Z""#,
        1579  +
            Arc::new(JsonCodecSettings::default()),
        1580  +
        );
        1581  +
        let ts = deser.read_timestamp(timestamp_schema()).unwrap();
        1582  +
        assert_eq!(ts, DateTime::from_secs(1700000000));
        1583  +
    }
        1584  +
        1585  +
    #[test]
        1586  +
    fn test_read_timestamp_invalid() {
        1587  +
        let mut deser = JsonDeserializer::new(b"true", Arc::new(JsonCodecSettings::default()));
        1588  +
        assert!(deser.read_timestamp(timestamp_schema()).is_err());
        1589  +
    }
        1590  +
        1591  +
    #[test]
        1592  +
    fn test_skip_value_empty_array() {
        1593  +
        // Regression: skip_value failed on [] because json_token_iter can't parse ']' as a value start
        1594  +
        use aws_smithy_schema::ShapeType;
        1595  +
        static KNOWN_MEMBER: Schema = Schema::new_member(
        1596  +
            aws_smithy_schema::shape_id!("test", "S"),
        1597  +
            ShapeType::String,
        1598  +
            "known",
        1599  +
            0,
        1600  +
        );
        1601  +
        static MEMBERS: &[&Schema] = &[&KNOWN_MEMBER];
        1602  +
        static TEST_SCHEMA: Schema = Schema::new_struct(
        1603  +
            aws_smithy_schema::shape_id!("test", "S"),
        1604  +
            ShapeType::Structure,
        1605  +
            MEMBERS,
        1606  +
        );
        1607  +
        1608  +
        let json = br#"{"known":"yes","Items":[],"extra":true}"#;
        1609  +
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
        1610  +
        let mut known_val = String::new();
        1611  +
        deser
        1612  +
            .read_struct(&TEST_SCHEMA, &mut |member, deser| {
        1613  +
                if member.member_name() == Some("known") {
        1614  +
                    known_val = deser.read_string(dummy_schema())?;
        1615  +
                }
        1616  +
                Ok(())
        1617  +
            })
        1618  +
            .unwrap();
        1619  +
        assert_eq!(known_val, "yes");
        1620  +
    }
        1621  +
        1622  +
    #[test]
        1623  +
    fn test_skip_value_nested_objects() {
        1624  +
        use aws_smithy_schema::ShapeType;
        1625  +
        static D_MEMBER: Schema = Schema::new_member(
        1626  +
            aws_smithy_schema::shape_id!("test", "S"),
        1627  +
            ShapeType::String,
        1628  +
            "d",
        1629  +
            0,
        1630  +
        );
        1631  +
        static MEMBERS: &[&Schema] = &[&D_MEMBER];
        1632  +
        static TEST_SCHEMA: Schema = Schema::new_struct(
        1633  +
            aws_smithy_schema::shape_id!("test", "S"),
        1634  +
            ShapeType::Structure,
        1635  +
            MEMBERS,
        1636  +
        );
        1637  +
        1638  +
        let json = br#"{"a":{"b":[1,2,{"c":3}]},"d":"ok"}"#;
        1639  +
        let mut deser = JsonDeserializer::new(json, Arc::new(JsonCodecSettings::default()));
        1640  +
        let mut d_val = String::new();
        1641  +
        deser
        1642  +
            .read_struct(&TEST_SCHEMA, &mut |member, deser| {
        1643  +
                if member.member_name() == Some("d") {
        1644  +
                    d_val = deser.read_string(dummy_schema())?;
        1645  +
                }
        1646  +
                Ok(())
        1647  +
            })
        1648  +
            .unwrap();
        1649  +
        assert_eq!(d_val, "ok");
        1650  +
    }
 1170   1651   
}

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

@@ -26,26 +160,172 @@
   46     46   
   47     47   
    /// Handles comma separators and member names before writing a value.
   48     48   
    /// When inside a map (map_depth > 0), restores expecting_map_key after
   49     49   
    /// the value so the next write_string is treated as a map key.
   50     50   
    fn prefix(&mut self, schema: &Schema) {
   51     51   
        if self.needs_comma {
   52     52   
            self.output.push(',');
   53     53   
        }
   54     54   
        if let Some(name) = self.field_name(schema) {
   55     55   
            self.output.push('"');
   56         -
            self.output.push_str(name);
          56  +
            self.output.push_str(&crate::escape::escape_string(name));
   57     57   
            self.output.push_str("\":");
   58     58   
        }
   59     59   
        self.needs_comma = true;
   60     60   
        // Inside a map, after writing a value the next write_string should be a key.
   61     61   
        // This is safe because write_string checks expecting_map_key *before* calling
   62     62   
        // prefix(), so this only affects the *next* write_string call.
   63     63   
        if self.map_depth > 0 {
   64     64   
            self.expecting_map_key = true;
   65     65   
        }
   66     66   
    }
   67     67   
   68     68   
    /// Resolves the JSON field name for a member schema.
   69     69   
    fn field_name<'a>(&self, schema: &'a Schema) -> Option<&'a str> {
   70     70   
        self.settings.member_to_field(schema)
   71     71   
    }
   72     72   
   73     73   
    /// Gets the timestamp format to use, respecting @timestampFormat trait.
   74     74   
    fn get_timestamp_format(&self, schema: &Schema) -> TimestampFormat {
   75     75   
        if let Some(ts_trait) = schema.timestamp_format() {
   76     76   
            return match ts_trait.format() {
   77     77   
                aws_smithy_schema::traits::TimestampFormat::EpochSeconds => {
   78     78   
                    TimestampFormat::EpochSeconds
   79     79   
                }
   80     80   
                aws_smithy_schema::traits::TimestampFormat::HttpDate => TimestampFormat::HttpDate,
   81     81   
                aws_smithy_schema::traits::TimestampFormat::DateTime => TimestampFormat::DateTime,
   82     82   
            };
   83     83   
        }
   84     84   
        self.settings.default_timestamp_format
   85     85   
    }
   86     86   
   87     87   
    fn write_json_value(&mut self, doc: &Document) {
   88     88   
        use crate::serialize::JsonValueWriter;
   89     89   
        let writer = JsonValueWriter::new(&mut self.output);
   90     90   
        writer.document(doc);
   91     91   
    }
   92     92   
}
   93     93   
          94  +
impl aws_smithy_schema::codec::FinishSerializer for JsonSerializer {
          95  +
    fn finish(self) -> Vec<u8> {
          96  +
        self.output.into_bytes()
          97  +
    }
          98  +
}
          99  +
   94    100   
impl ShapeSerializer for JsonSerializer {
   95    101   
    fn write_struct(
   96    102   
        &mut self,
   97    103   
        schema: &Schema,
   98    104   
        value: &dyn SerializableStruct,
   99    105   
    ) -> Result<(), SerdeError> {
  100    106   
        self.prefix(schema);
  101    107   
        self.output.push('{');
  102         -
        let saved = self.needs_comma;
         108  +
        let saved_comma = self.needs_comma;
  103    109   
        let saved_depth = self.map_depth;
         110  +
        let saved_map_key = self.expecting_map_key;
  104    111   
        self.needs_comma = false;
  105         -
        // Reset map_depth so struct members don't trigger map-key logic in prefix().
         112  +
        // Reset map state so struct members don't trigger map-key logic.
  106    113   
        // Restored after the struct body so an enclosing map resumes correctly.
  107    114   
        self.map_depth = 0;
         115  +
        self.expecting_map_key = false;
  108    116   
        value.serialize_members(self)?;
  109    117   
        self.output.push('}');
  110         -
        self.needs_comma = saved;
         118  +
        self.needs_comma = saved_comma;
  111    119   
        self.map_depth = saved_depth;
         120  +
        self.expecting_map_key = saved_map_key;
  112    121   
        Ok(())
  113    122   
    }
  114    123   
  115    124   
    fn write_list(
  116    125   
        &mut self,
  117    126   
        schema: &Schema,
  118    127   
        write_elements: &dyn Fn(&mut dyn ShapeSerializer) -> Result<(), SerdeError>,
  119    128   
    ) -> Result<(), SerdeError> {
  120    129   
        self.prefix(schema);
  121    130   
        self.output.push('[');
  122    131   
        let saved = self.needs_comma;
  123    132   
        let saved_depth = self.map_depth;
         133  +
        let saved_map_key = self.expecting_map_key;
  124    134   
        self.needs_comma = false;
  125         -
        // Reset map_depth so list elements don't trigger map-key logic in prefix().
         135  +
        // Reset map state so list elements don't trigger map-key logic in prefix().
  126    136   
        self.map_depth = 0;
         137  +
        self.expecting_map_key = false;
  127    138   
        write_elements(self)?;
  128    139   
        self.output.push(']');
  129    140   
        self.needs_comma = saved;
  130    141   
        self.map_depth = saved_depth;
         142  +
        self.expecting_map_key = saved_map_key;
  131    143   
        Ok(())
  132    144   
    }
  133    145   
  134    146   
    fn write_map(
  135    147   
        &mut self,
  136    148   
        schema: &Schema,
  137    149   
        write_entries: &dyn Fn(&mut dyn ShapeSerializer) -> Result<(), SerdeError>,
  138    150   
    ) -> Result<(), SerdeError> {
  139    151   
        self.prefix(schema);
  140    152   
        self.output.push('{');
@@ -169,181 +240,276 @@
  189    201   
        use std::fmt::Write;
  190    202   
        self.prefix(schema);
  191    203   
        write!(&mut self.output, "{}", value).map_err(|e| SerdeError::WriteFailed {
  192    204   
            message: e.to_string(),
  193    205   
        })
  194    206   
    }
  195    207   
  196    208   
    fn write_float(&mut self, schema: &Schema, value: f32) -> Result<(), SerdeError> {
  197    209   
        use std::fmt::Write;
  198    210   
        self.prefix(schema);
         211  +
        if value.is_nan() {
         212  +
            self.output.push_str("\"NaN\"");
         213  +
            Ok(())
         214  +
        } else if value.is_infinite() {
         215  +
            if value.is_sign_positive() {
         216  +
                self.output.push_str("\"Infinity\"");
         217  +
            } else {
         218  +
                self.output.push_str("\"-Infinity\"");
         219  +
            }
         220  +
            Ok(())
         221  +
        } else {
  199    222   
            write!(&mut self.output, "{}", value).map_err(|e| SerdeError::WriteFailed {
  200    223   
                message: e.to_string(),
  201    224   
            })
  202    225   
        }
         226  +
    }
  203    227   
  204    228   
    fn write_double(&mut self, schema: &Schema, value: f64) -> Result<(), SerdeError> {
  205    229   
        use std::fmt::Write;
  206    230   
        self.prefix(schema);
         231  +
        if value.is_nan() {
         232  +
            self.output.push_str("\"NaN\"");
         233  +
            Ok(())
         234  +
        } else if value.is_infinite() {
         235  +
            if value.is_sign_positive() {
         236  +
                self.output.push_str("\"Infinity\"");
         237  +
            } else {
         238  +
                self.output.push_str("\"-Infinity\"");
         239  +
            }
         240  +
            Ok(())
         241  +
        } else {
  207    242   
            write!(&mut self.output, "{}", value).map_err(|e| SerdeError::WriteFailed {
  208    243   
                message: e.to_string(),
  209    244   
            })
  210    245   
        }
         246  +
    }
  211    247   
  212    248   
    fn write_big_integer(&mut self, schema: &Schema, value: &BigInteger) -> Result<(), SerdeError> {
  213    249   
        self.prefix(schema);
  214    250   
        self.output.push_str(value.as_ref());
  215    251   
        Ok(())
  216    252   
    }
  217    253   
  218    254   
    fn write_big_decimal(&mut self, schema: &Schema, value: &BigDecimal) -> Result<(), SerdeError> {
  219    255   
        self.prefix(schema);
  220    256   
        self.output.push_str(value.as_ref());
@@ -265,301 +324,361 @@
  285    321   
        self.prefix(schema);
  286    322   
        self.output.push_str("null");
  287    323   
        Ok(())
  288    324   
    }
  289    325   
}
  290    326   
  291    327   
#[cfg(test)]
  292    328   
mod tests {
  293    329   
    use super::*;
  294    330   
    use aws_smithy_schema::prelude::*;
         331  +
    use aws_smithy_schema::ShapeType;
  295    332   
  296    333   
    #[test]
  297    334   
    fn test_write_boolean() {
  298    335   
        let mut ser = JsonSerializer::new(Arc::new(JsonCodecSettings::default()));
  299    336   
        ser.write_boolean(&BOOLEAN, true).unwrap();
  300    337   
        let output = ser.finish();
  301    338   
        assert_eq!(String::from_utf8(output).unwrap(), "true");
  302    339   
    }
  303    340   
  304    341   
    #[test]
@@ -607,644 +637,719 @@
  627    664   
        assert_eq!(output, r#"{"foo":"hello","Baz":42}"#);
  628    665   
  629    666   
        // With use_json_name=false, "bar" should stay as "bar"
  630    667   
        let mut ser = JsonSerializer::new(Arc::new(
  631    668   
            JsonCodecSettings::builder().use_json_name(false).build(),
  632    669   
        ));
  633    670   
        ser.write_struct(&struct_schema, &TestStruct).unwrap();
  634    671   
        let output = String::from_utf8(ser.finish()).unwrap();
  635    672   
        assert_eq!(output, r#"{"foo":"hello","bar":42}"#);
  636    673   
    }
         674  +
         675  +
    #[test]
         676  +
    fn struct_inside_map_serializes_member_names_correctly() {
         677  +
        // Regression test: when a struct is a map value, the map's expecting_map_key
         678  +
        // flag must not leak into the struct's member serialization.
         679  +
        use aws_smithy_schema::serde::{SerializableStruct, ShapeSerializer};
         680  +
         681  +
        static INNER_NAME: Schema = Schema::new_member(
         682  +
            aws_smithy_schema::shape_id!("test", "Inner"),
         683  +
            ShapeType::String,
         684  +
            "name",
         685  +
            0,
         686  +
        );
         687  +
        static INNER_MEMBERS: &[&Schema] = &[&INNER_NAME];
         688  +
        static INNER_SCHEMA: Schema = Schema::new_struct(
         689  +
            aws_smithy_schema::shape_id!("test", "Inner"),
         690  +
            ShapeType::Structure,
         691  +
            INNER_MEMBERS,
         692  +
        );
         693  +
         694  +
        struct Inner;
         695  +
        impl SerializableStruct for Inner {
         696  +
            fn serialize_members(
         697  +
                &self,
         698  +
                ser: &mut dyn ShapeSerializer,
         699  +
            ) -> Result<(), aws_smithy_schema::serde::SerdeError> {
         700  +
                ser.write_string(&INNER_NAME, "Alice")
         701  +
            }
         702  +
        }
         703  +
         704  +
        static MAP_SCHEMA: Schema = Schema::new(
         705  +
            aws_smithy_schema::shape_id!("test", "MyMap"),
         706  +
            ShapeType::Map,
         707  +
        );
         708  +
         709  +
        let mut ser = JsonSerializer::new(Arc::new(JsonCodecSettings::default()));
         710  +
        ser.write_map(&MAP_SCHEMA, &|ser| {
         711  +
            ser.write_string(&aws_smithy_schema::prelude::STRING, "key1")?;
         712  +
            ser.write_struct(&INNER_SCHEMA, &Inner)?;
         713  +
            Ok(())
         714  +
        })
         715  +
        .unwrap();
         716  +
        let output = String::from_utf8(ser.finish()).unwrap();
         717  +
        assert_eq!(output, r#"{"key1":{"name":"Alice"}}"#);
         718  +
    }
  637    719   
}