1use std::borrow::Cow;
7
8use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime};
9use minicbor::decode::Error;
10
11use crate::data::Type;
12
13#[derive(Debug, Clone)]
21pub struct Decoder<'b> {
22 decoder: minicbor::Decoder<'b>,
23}
24
25#[derive(Debug)]
28pub struct DeserializeError {
29 #[allow(dead_code)]
30 _inner: Error,
31}
32
33impl std::fmt::Display for DeserializeError {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 self._inner.fmt(f)
36 }
37}
38
39impl std::error::Error for DeserializeError {}
40
41impl DeserializeError {
42 pub(crate) fn new(inner: Error) -> Self {
43 Self { _inner: inner }
44 }
45
46 pub fn unexpected_union_variant(unexpected_type: Type, at: usize) -> Self {
48 Self {
49 _inner: Error::type_mismatch(unexpected_type.into_minicbor_type())
50 .with_message("encountered unexpected union variant; expected end of union")
51 .at(at),
52 }
53 }
54
55 pub fn unknown_union_variant(variant_name: &str, at: usize) -> Self {
57 Self {
58 _inner: Error::message(format!("encountered unknown union variant {variant_name}"))
59 .at(at),
60 }
61 }
62
63 pub fn mixed_union_variants(at: usize) -> Self {
67 Self {
68 _inner: Error::message(
69 "encountered mixed variants in union; expected a single union variant to be set",
70 )
71 .at(at),
72 }
73 }
74
75 pub fn expected_end_of_stream(at: usize) -> Self {
77 Self {
78 _inner: Error::message("encountered additional data; expected end of stream").at(at),
79 }
80 }
81
82 pub fn custom(message: impl Into<Cow<'static, str>>, at: usize) -> Self {
84 Self {
85 _inner: Error::message(message.into()).at(at),
86 }
87 }
88
89 pub fn is_type_mismatch(&self) -> bool {
93 self._inner.is_type_mismatch()
94 }
95}
96
97macro_rules! delegate_method {
113 ($($(#[$meta:meta])* $wrapper_name:ident => $encoder_name:ident($result_type:ty);)+) => {
114 $(
115 pub fn $wrapper_name(&mut self) -> Result<$result_type, DeserializeError> {
116 self.decoder.$encoder_name().map_err(DeserializeError::new)
117 }
118 )+
119 };
120}
121
122impl<'b> Decoder<'b> {
123 pub fn new(bytes: &'b [u8]) -> Self {
124 Self {
125 decoder: minicbor::Decoder::new(bytes),
126 }
127 }
128
129 pub fn datatype(&self) -> Result<Type, DeserializeError> {
130 self.decoder
131 .datatype()
132 .map(Type::new)
133 .map_err(DeserializeError::new)
134 }
135
136 delegate_method! {
137 skip => skip(());
139 boolean => bool(bool);
141 byte => i8(i8);
143 short => i16(i16);
145 integer => i32(i32);
147 long => i64(i64);
149 float => f32(f32);
151 double => f64(f64);
153 null => null(());
155 list => array(Option<u64>);
157 map => map(Option<u64>);
159 }
160
161 pub fn position(&self) -> usize {
163 self.decoder.position()
164 }
165
166 pub fn set_position(&mut self, pos: usize) {
168 self.decoder.set_position(pos)
169 }
170
171 pub fn str(&mut self) -> Result<Cow<'b, str>, DeserializeError> {
176 let bookmark = self.decoder.position();
177 match self.decoder.str() {
178 Ok(str_value) => Ok(Cow::Borrowed(str_value)),
179 Err(e) if e.is_type_mismatch() => {
180 self.decoder.set_position(bookmark);
183 Ok(Cow::Owned(self.string()?))
184 }
185 Err(e) => Err(DeserializeError::new(e)),
186 }
187 }
188
189 pub fn string(&mut self) -> Result<String, DeserializeError> {
192 let mut iter = self.decoder.str_iter().map_err(DeserializeError::new)?;
193 let head = iter.next();
194
195 let decoded_string = match head {
196 None => String::new(),
197 Some(head) => {
198 let mut combined_chunks = String::from(head.map_err(DeserializeError::new)?);
199 for chunk in iter {
200 combined_chunks.push_str(chunk.map_err(DeserializeError::new)?);
201 }
202 combined_chunks
203 }
204 };
205
206 Ok(decoded_string)
207 }
208
209 pub fn blob(&mut self) -> Result<Blob, DeserializeError> {
212 let iter = self.decoder.bytes_iter().map_err(DeserializeError::new)?;
213 let parts: Vec<&[u8]> = iter
214 .collect::<Result<_, _>>()
215 .map_err(DeserializeError::new)?;
216
217 Ok(if parts.len() == 1 {
218 Blob::new(parts[0]) } else {
220 Blob::new(parts.concat()) })
222 }
223
224 pub fn timestamp(&mut self) -> Result<DateTime, DeserializeError> {
227 let tag = self.decoder.tag().map_err(DeserializeError::new)?;
228 let timestamp_tag = minicbor::data::Tag::from(minicbor::data::IanaTag::Timestamp);
229
230 if tag != timestamp_tag {
231 Err(DeserializeError::new(Error::message(
232 "expected timestamp tag",
233 )))
234 } else {
235 let epoch_seconds = match self.decoder.datatype().map_err(DeserializeError::new)? {
245 minicbor::data::Type::F16
246 | minicbor::data::Type::F32
247 | minicbor::data::Type::F64 => self.decoder.f64().map_err(DeserializeError::new)?,
248 _ => self.decoder.i64().map_err(DeserializeError::new)? as f64,
249 };
250 let mut result = DateTime::from_secs_f64(epoch_seconds);
251 let subsec_nanos = result.subsec_nanos();
252 result.set_subsec_nanos((subsec_nanos / 1_000_000) * 1_000_000);
253 Ok(result)
254 }
255 }
256
257 pub fn big_integer(&mut self) -> Result<BigInteger, DeserializeError> {
264 self.bigint()?
265 .to_string()
266 .parse()
267 .map_err(|_| DeserializeError::new(Error::message("invalid bignum value")))
268 }
269
270 pub fn big_decimal(&mut self) -> Result<BigDecimal, DeserializeError> {
276 let tag_position = self.decoder.position();
277 let tag = self.decoder.tag().map_err(DeserializeError::new)?;
278 if tag.as_u64() != 4 {
279 return Err(DeserializeError::new(
280 Error::message("expected CBOR tag 4 (decimal fraction)").at(tag_position),
281 ));
282 }
283
284 let len = self.decoder.array().map_err(DeserializeError::new)?;
285 if let Some(len) = len {
286 if len != 2 {
287 return Err(DeserializeError::new(Error::message(
288 "expected decimal fraction array with two elements",
289 )));
290 }
291 }
292
293 let exponent = self.decimal_exponent()?;
294 let mantissa = self.bigint()?;
295
296 if len.is_none() {
297 match self.decoder.datatype().map_err(DeserializeError::new)? {
298 minicbor::data::Type::Break => {
299 self.decoder.skip().map_err(DeserializeError::new)?;
300 }
301 _ => {
302 return Err(DeserializeError::new(Error::message(
303 "expected decimal fraction array with two elements",
304 )));
305 }
306 }
307 }
308
309 let scale = exponent.checked_neg().ok_or_else(|| {
310 DeserializeError::new(Error::message(
311 "big decimal fraction exponent is outside the supported range",
312 ))
313 })?;
314 let value = bigdecimal::BigDecimal::new(mantissa, scale);
315 value
316 .to_string()
317 .parse()
318 .map_err(|_| DeserializeError::new(Error::message("invalid decimal fraction value")))
319 }
320
321 fn decimal_exponent(&mut self) -> Result<i64, DeserializeError> {
322 let value = match self.decoder.datatype().map_err(DeserializeError::new)? {
323 minicbor::data::Type::U8
324 | minicbor::data::Type::U16
325 | minicbor::data::Type::U32
326 | minicbor::data::Type::U64 => {
327 let value = self.decoder.u64().map_err(DeserializeError::new)?;
328 i64::try_from(value).map_err(|_| {
329 DeserializeError::new(Error::message(
330 "big decimal fraction exponent is outside the supported range",
331 ))
332 })?
333 }
334 minicbor::data::Type::I8
335 | minicbor::data::Type::I16
336 | minicbor::data::Type::I32
337 | minicbor::data::Type::I64 => self.decoder.i64().map_err(DeserializeError::new)?,
338 minicbor::data::Type::Int => {
339 let value: i128 = self.decoder.int().map_err(DeserializeError::new)?.into();
340 i64::try_from(value).map_err(|_| {
341 DeserializeError::new(Error::message(
342 "big decimal fraction exponent is outside the supported range",
343 ))
344 })?
345 }
346 _ => {
347 return Err(DeserializeError::new(Error::message(
348 "expected integer decimal fraction exponent",
349 )));
350 }
351 };
352 Ok(value)
353 }
354
355 fn bigint(&mut self) -> Result<num_bigint::BigInt, DeserializeError> {
356 use num_bigint::BigInt;
357
358 match self.decoder.datatype().map_err(DeserializeError::new)? {
359 minicbor::data::Type::Tag => {
360 let tag = self.decoder.tag().map_err(DeserializeError::new)?;
361 let bytes = self.decoder.bytes().map_err(DeserializeError::new)?;
362 let n = BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes);
363
364 let value = match tag.as_u64() {
365 2 => n,
366 3 => -n - 1, _ => {
368 return Err(DeserializeError::new(Error::message(
369 "expected CBOR tag 2 (positive bignum) or tag 3 (negative bignum)",
370 )));
371 }
372 };
373 Ok(value)
374 }
375 minicbor::data::Type::U8
376 | minicbor::data::Type::U16
377 | minicbor::data::Type::U32
378 | minicbor::data::Type::U64 => {
379 let value = self.decoder.u64().map_err(DeserializeError::new)?;
380 Ok(BigInt::from(value))
381 }
382 minicbor::data::Type::I8
383 | minicbor::data::Type::I16
384 | minicbor::data::Type::I32
385 | minicbor::data::Type::I64 => {
386 let value = self.decoder.i64().map_err(DeserializeError::new)?;
387 Ok(BigInt::from(value))
388 }
389 minicbor::data::Type::Int => {
392 let int_val = self.decoder.int().map_err(DeserializeError::new)?;
393 let value: i128 = int_val.into();
394 Ok(BigInt::from(value))
395 }
396 _ => Err(DeserializeError::new(Error::message(
397 "expected CBOR integer or bignum tag",
398 ))),
399 }
400 }
401}
402
403#[allow(dead_code)] #[derive(Debug)]
405pub struct ArrayIter<'a, 'b, T> {
406 inner: minicbor::decode::ArrayIter<'a, 'b, T>,
407}
408
409impl<'b, T: minicbor::Decode<'b, ()>> Iterator for ArrayIter<'_, 'b, T> {
410 type Item = Result<T, DeserializeError>;
411
412 fn next(&mut self) -> Option<Self::Item> {
413 self.inner
414 .next()
415 .map(|opt| opt.map_err(DeserializeError::new))
416 }
417}
418
419#[allow(dead_code)] #[derive(Debug)]
421pub struct MapIter<'a, 'b, K, V> {
422 inner: minicbor::decode::MapIter<'a, 'b, K, V>,
423}
424
425impl<'b, K, V> Iterator for MapIter<'_, 'b, K, V>
426where
427 K: minicbor::Decode<'b, ()>,
428 V: minicbor::Decode<'b, ()>,
429{
430 type Item = Result<(K, V), DeserializeError>;
431
432 fn next(&mut self) -> Option<Self::Item> {
433 self.inner
434 .next()
435 .map(|opt| opt.map_err(DeserializeError::new))
436 }
437}
438
439pub fn set_optional<B, F>(builder: B, decoder: &mut Decoder, f: F) -> Result<B, DeserializeError>
440where
441 F: Fn(B, &mut Decoder) -> Result<B, DeserializeError>,
442{
443 match decoder.datatype()? {
444 crate::data::Type::Null => {
445 decoder.null()?;
446 Ok(builder)
447 }
448 _ => f(builder, decoder),
449 }
450}
451
452#[cfg(test)]
453mod tests {
454 use crate::Decoder;
455 use aws_smithy_types::date_time::Format;
456
457 #[test]
458 fn test_definite_str_is_cow_borrowed() {
459 let definite_bytes = [
461 0x6a, 0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x4b, 0x65, 0x79,
462 ];
463 let mut decoder = Decoder::new(&definite_bytes);
464 let member = decoder.str().expect("could not decode str");
465 assert_eq!(member, "thisIsAKey");
466 assert!(matches!(member, std::borrow::Cow::Borrowed(_)));
467 }
468
469 #[test]
470 fn test_indefinite_str_is_cow_owned() {
471 let indefinite_bytes = [
473 0x7f, 0x64, 0x74, 0x68, 0x69, 0x73, 0x62, 0x49, 0x73, 0x61, 0x41, 0x63, 0x4b, 0x65,
474 0x79, 0xff,
475 ];
476 let mut decoder = Decoder::new(&indefinite_bytes);
477 let member = decoder.str().expect("could not decode str");
478 assert_eq!(member, "thisIsAKey");
479 assert!(matches!(member, std::borrow::Cow::Owned(_)));
480 }
481
482 #[test]
483 fn test_empty_str_works() {
484 let bytes = [0x60];
485 let mut decoder = Decoder::new(&bytes);
486 let member = decoder.str().expect("could not decode empty str");
487 assert_eq!(member, "");
488 }
489
490 #[test]
491 fn test_empty_blob_works() {
492 let bytes = [0x40];
493 let mut decoder = Decoder::new(&bytes);
494 let member = decoder.blob().expect("could not decode an empty blob");
495 assert_eq!(member, aws_smithy_types::Blob::new([]));
496 }
497
498 #[test]
499 fn test_indefinite_length_blob() {
500 let indefinite_bytes = [
503 0x5f, 0x50, 0x69, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x2d, 0x62,
504 0x79, 0x74, 0x65, 0x2c, 0x49, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x65, 0x64, 0x2c,
505 0x4e, 0x20, 0x6f, 0x6e, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6d, 0x6d,
506 0x61, 0xff,
507 ];
508 let mut decoder = Decoder::new(&indefinite_bytes);
509 let member = decoder.blob().expect("could not decode blob");
510 assert_eq!(
511 member,
512 aws_smithy_types::Blob::new("indefinite-byte, chunked, on each comma".as_bytes())
513 );
514 }
515
516 #[test]
517 fn test_timestamp_should_be_truncated_to_fit_millisecond_precision() {
518 let bytes = [
521 0xc1, 0xfb, 0x41, 0xcc, 0x37, 0xdb, 0x38, 0x0f, 0xbe, 0x77, 0xff,
522 ];
523 let mut decoder = Decoder::new(&bytes);
524 let timestamp = decoder.timestamp().expect("should decode timestamp");
525 assert_eq!(
526 timestamp,
527 aws_smithy_types::date_time::DateTime::from_str(
528 "2000-01-02T20:34:56.123Z",
529 Format::DateTime
530 )
531 .unwrap()
532 );
533 }
534
535 #[test]
536 fn big_integer_round_trip_positive() {
537 for value in ["0", "1", "23", "256", "65535", "18446744073709551615"] {
538 let mut encoder = crate::Encoder::new(Vec::new());
539 encoder.big_integer(&value.parse().unwrap());
540 let bytes = encoder.into_writer();
541 let mut decoder = Decoder::new(&bytes);
542 let result = decoder.big_integer().expect("should decode");
543 assert_eq!(result.as_ref(), value, "round-trip failed for {value}");
544 }
545 }
546
547 #[test]
548 fn big_integer_round_trip_negative() {
549 for value in ["-1", "-42", "-256", "-18446744073709551616"] {
550 let mut encoder = crate::Encoder::new(Vec::new());
551 encoder.big_integer(&value.parse().unwrap());
552 let bytes = encoder.into_writer();
553 let mut decoder = Decoder::new(&bytes);
554 let result = decoder.big_integer().expect("should decode");
555 assert_eq!(result.as_ref(), value, "round-trip failed for {value}");
556 }
557 }
558
559 #[test]
560 fn big_integer_round_trip_large() {
561 let large_pos = "123456789012345678901234567890";
562 let large_neg = "-123456789012345678901234567890";
563 for value in [large_pos, large_neg] {
564 let mut encoder = crate::Encoder::new(Vec::new());
565 encoder.big_integer(&value.parse().unwrap());
566 let bytes = encoder.into_writer();
567 let mut decoder = Decoder::new(&bytes);
568 let result = decoder.big_integer().expect("should decode");
569 assert_eq!(result.as_ref(), value, "round-trip failed for {value}");
570 }
571 }
572
573 #[test]
574 fn big_integer_rfc8949_appendix_a_positive() {
575 let bytes = [
577 0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 ];
579 let mut decoder = Decoder::new(&bytes);
580 let result = decoder.big_integer().expect("should decode");
581 assert_eq!(result.as_ref(), "18446744073709551616");
582 }
583
584 #[test]
585 fn big_integer_rfc8949_appendix_a_negative() {
586 let bytes = [
588 0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 ];
590 let mut decoder = Decoder::new(&bytes);
591 let result = decoder.big_integer().expect("should decode");
592 assert_eq!(result.as_ref(), "-18446744073709551617");
593 }
594
595 #[test]
596 fn big_integer_from_plain_cbor_unsigned() {
597 let mut enc = minicbor::Encoder::new(Vec::new());
598 enc.u64(9999).unwrap();
599 let bytes = enc.into_writer();
600 let mut decoder = Decoder::new(&bytes);
601 let result = decoder.big_integer().expect("should decode plain integer");
602 assert_eq!(result.as_ref(), "9999");
603 }
604
605 #[test]
606 fn big_integer_from_plain_cbor_negative() {
607 let mut enc = minicbor::Encoder::new(Vec::new());
608 enc.i64(-500).unwrap();
609 let bytes = enc.into_writer();
610 let mut decoder = Decoder::new(&bytes);
611 let result = decoder
612 .big_integer()
613 .expect("should decode negative plain integer");
614 assert_eq!(result.as_ref(), "-500");
615 }
616
617 #[test]
618 fn big_integer_from_plain_cbor_positive_signed() {
619 let mut enc = minicbor::Encoder::new(Vec::new());
622 enc.i64(123).unwrap();
623 let bytes = enc.into_writer();
624 let mut decoder = Decoder::new(&bytes);
625 let result = decoder
626 .big_integer()
627 .expect("should decode positive plain integer");
628 assert_eq!(result.as_ref(), "123");
629 }
630
631 #[test]
632 fn big_integer_tag3_empty_byte_string() {
633 let bytes = [0xc3, 0x40]; let mut decoder = Decoder::new(&bytes);
636 let result = decoder.big_integer().expect("should decode");
637 assert_eq!(result.as_ref(), "-1");
638 }
639
640 #[test]
641 fn big_integer_tag2_empty_byte_string() {
642 let bytes = [0xc2, 0x40]; let mut decoder = Decoder::new(&bytes);
645 let result = decoder.big_integer().expect("should decode");
646 assert_eq!(result.as_ref(), "0");
647 }
648
649 #[test]
650 fn big_integer_rejects_invalid_tag() {
651 let bytes = [0xc4, 0x82, 0x21, 0x19, 0x6a, 0xb3];
653 let mut decoder = Decoder::new(&bytes);
654 assert!(decoder.big_integer().is_err());
655 }
656
657 #[test]
658 fn big_integer_decode_major_type_1_exceeding_i64() {
659 let bytes = [0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
663 let mut decoder = Decoder::new(&bytes);
664 let result = decoder
665 .big_integer()
666 .expect("should decode major type 1 > i64::MAX");
667 assert_eq!(result.as_ref(), "-18446744073709551616");
668 }
669
670 #[test]
671 fn big_decimal_rfc8949_example() {
672 let bytes = [0xc4, 0x82, 0x21, 0x19, 0x6a, 0xb3];
674 let mut decoder = Decoder::new(&bytes);
675 let result = decoder.big_decimal().expect("should decode");
676 assert_eq!(result.as_ref(), "273.15");
677 }
678
679 #[test]
680 fn big_decimal_round_trip_preserves_numeric_value() {
681 for value in [
682 "0",
683 "0.0",
684 "-0.0",
685 "+5",
686 ".5",
687 "5.",
688 "1.2300",
689 "-273.15",
690 "1.23e10",
691 "1e2",
692 "1.5E+3",
693 "1E-10",
694 "0.123456789012345678901234567890",
695 "18446744073709551616",
696 "-18446744073709551617",
697 ] {
698 let mut encoder = crate::Encoder::new(Vec::new());
699 encoder.big_decimal(&value.parse().unwrap());
700 let bytes = encoder.into_writer();
701 let mut decoder = Decoder::new(&bytes);
702 let result = decoder.big_decimal().expect("should decode");
703
704 let actual: bigdecimal::BigDecimal = result.as_ref().parse().unwrap();
708 let expected: bigdecimal::BigDecimal = value.parse().unwrap();
709 assert_eq!(
710 actual,
711 expected,
712 "round-trip failed for {value}, decoded as {}",
713 result.as_ref()
714 );
715 }
716 }
717
718 #[test]
719 fn big_decimal_accepts_indefinite_array() {
720 let bytes = [0xc4, 0x9f, 0x21, 0x19, 0x6a, 0xb3, 0xff];
721 let mut decoder = Decoder::new(&bytes);
722 let result = decoder.big_decimal().expect("should decode");
723 assert_eq!(result.as_ref(), "273.15");
724 }
725
726 #[test]
727 fn big_decimal_rejects_invalid_tag() {
728 let bytes = [0x00, 0xc5, 0x82, 0x00, 0x01];
729 let mut decoder = Decoder::new(&bytes);
730 decoder.set_position(1);
731 let error = decoder.big_decimal().expect_err("tag 5 must be rejected");
732 assert_eq!(
733 error.to_string(),
734 "decode error at position 1: expected CBOR tag 4 (decimal fraction)"
735 );
736 }
737
738 #[test]
739 fn big_decimal_rejects_invalid_array_length() {
740 for bytes in [
741 &[0xc4, 0x81, 0x00][..],
742 &[0xc4, 0x83, 0x00, 0x01, 0x02][..],
743 &[0xc4, 0x9f, 0x00, 0x01, 0x02, 0xff][..],
744 ] {
745 let mut decoder = Decoder::new(bytes);
746 assert!(decoder.big_decimal().is_err());
747 }
748 }
749
750 #[test]
751 fn big_decimal_rejects_non_integer_components() {
752 for bytes in [&[0xc4, 0x82, 0xf4, 0x01][..], &[0xc4, 0x82, 0x00, 0xf4][..]] {
753 let mut decoder = Decoder::new(bytes);
754 assert!(decoder.big_decimal().is_err());
755 }
756 }
757
758 #[test]
759 fn big_decimal_rejects_unsupported_exponents() {
760 for bytes in [
761 &[
763 0xc4, 0x82, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
764 ][..],
765 &[
767 0xc4, 0x82, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
768 ][..],
769 ] {
770 let mut decoder = Decoder::new(bytes);
771 let error = decoder
772 .big_decimal()
773 .expect_err("unsupported exponent must be rejected");
774 assert_eq!(
775 error.to_string(),
776 "decode error: big decimal fraction exponent is outside the supported range"
777 );
778 }
779 }
780
781 #[test]
782 fn test_timestamp_integer_epoch_seconds() {
783 let bytes = [0xc1u8, 0x1a, 0x65, 0x53, 0xf1, 0x00];
786 let mut decoder = Decoder::new(&bytes);
787 let timestamp = decoder
788 .timestamp()
789 .expect("should decode integer timestamp");
790 assert_eq!(timestamp, aws_smithy_types::DateTime::from_secs(1700000000));
791 }
792}