serde_shape/impls/
time.rs1use alloc::vec;
16use alloc::vec::Vec;
17use core::any::type_name;
18use core::time::Duration;
19#[cfg(feature = "std")]
20use std::time::SystemTime;
21
22use crate::DefaultShape;
23use crate::DeserializeContainerAttributes;
24use crate::DeserializeDefinitionKind;
25use crate::DeserializeFieldShape;
26use crate::DeserializeShape;
27use crate::DeserializeShapeContext;
28use crate::DeserializeStructShape;
29use crate::FieldMember;
30use crate::FieldWireShape;
31use crate::FieldsStyle;
32use crate::SerializeContainerAttributes;
33use crate::SerializeDefinitionKind;
34use crate::SerializeFieldShape;
35use crate::SerializeShape;
36use crate::SerializeShapeContext;
37use crate::SerializeStructShape;
38use crate::ShapeRef;
39use crate::TypeName;
40
41macro_rules! time_shape {
42 ($ty:ty, $name:literal, $($field:literal => $shape:expr),+ $(,)?) => {
43 impl SerializeShape for $ty {
44 fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
45 serialize_time_shape(
46 context,
47 type_name::<Self>(),
48 $name,
49 [$(($field, $shape)),+],
50 )
51 }
52 }
53
54 impl DeserializeShape for $ty {
55 fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
56 deserialize_time_shape(
57 context,
58 type_name::<Self>(),
59 $name,
60 [$(($field, $shape)),+],
61 )
62 }
63 }
64 };
65}
66
67time_shape!(Duration, "Duration", "secs" => ShapeRef::U64, "nanos" => ShapeRef::U32);
68
69#[cfg(feature = "std")]
70time_shape!(
71 SystemTime,
72 "SystemTime",
73 "secs_since_epoch" => ShapeRef::U64,
74 "nanos_since_epoch" => ShapeRef::U32,
75);
76
77fn serialize_time_shape<const N: usize>(
78 context: &mut SerializeShapeContext,
79 rust_name: &'static str,
80 name: &'static str,
81 fields: [(&'static str, ShapeRef); N],
82) -> ShapeRef {
83 let fields: Vec<_> = fields
84 .into_iter()
85 .map(|(name, shape)| SerializeFieldShape {
86 member: FieldMember::Named(name),
87 name,
88 description: None,
89 wire_shape: FieldWireShape::Value(shape),
90 skip_if: None,
91 })
92 .collect();
93 context.define_named_type(TypeName { rust_name, name }, move |_| {
94 SerializeDefinitionKind::Struct(SerializeStructShape {
95 style: FieldsStyle::Struct,
96 fields,
97 attributes: SerializeContainerAttributes::default(),
98 })
99 })
100}
101
102fn deserialize_time_shape<const N: usize>(
103 context: &mut DeserializeShapeContext,
104 rust_name: &'static str,
105 name: &'static str,
106 fields: [(&'static str, ShapeRef); N],
107) -> ShapeRef {
108 let fields: Vec<_> = fields
109 .into_iter()
110 .map(|(name, shape)| DeserializeFieldShape {
111 member: FieldMember::Named(name),
112 name,
113 aliases: vec![name],
114 description: None,
115 wire_shape: FieldWireShape::Value(shape),
116 default: DefaultShape::None,
117 })
118 .collect();
119 context.define_named_type(TypeName { rust_name, name }, move |_| {
120 DeserializeDefinitionKind::Struct(DeserializeStructShape {
121 style: FieldsStyle::Struct,
122 fields,
123 attributes: DeserializeContainerAttributes {
124 deny_unknown_fields: true,
125 ..DeserializeContainerAttributes::default()
126 },
127 })
128 })
129}