1use alloc::boxed::Box;
16use alloc::vec;
17use core::net::IpAddr;
18use core::net::Ipv4Addr;
19use core::net::Ipv6Addr;
20use core::net::SocketAddr;
21use core::net::SocketAddrV4;
22use core::net::SocketAddrV6;
23
24use crate::DefaultShape;
25use crate::DeserializeContainerAttributes;
26use crate::DeserializeDefinitionKind;
27use crate::DeserializeEnumShape;
28use crate::DeserializeFieldShape;
29use crate::DeserializeShape;
30use crate::DeserializeShapeContext;
31use crate::DeserializeVariantContent;
32use crate::DeserializeVariantShape;
33use crate::FieldMember;
34use crate::FieldWireShape;
35use crate::FieldsStyle;
36use crate::SerializeContainerAttributes;
37use crate::SerializeDefinitionKind;
38use crate::SerializeEnumShape;
39use crate::SerializeFieldShape;
40use crate::SerializeShape;
41use crate::SerializeShapeContext;
42use crate::SerializeVariantContent;
43use crate::SerializeVariantShape;
44use crate::ShapeRef;
45use crate::Tagging;
46use crate::TypeName;
47
48macro_rules! union_shape {
49 ($ty:ty => $binary:expr) => {
50 impl SerializeShape for $ty {
51 fn serialize_shape_in(_context: &mut SerializeShapeContext) -> ShapeRef {
52 ShapeRef::union([ShapeRef::String, $binary])
53 }
54 }
55
56 impl DeserializeShape for $ty {
57 fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
58 ShapeRef::union([ShapeRef::String, $binary])
59 }
60 }
61 };
62}
63
64union_shape!(Ipv4Addr => ipv4_binary_shape());
65union_shape!(Ipv6Addr => ipv6_binary_shape());
66union_shape!(SocketAddrV4 => socket_v4_binary_shape());
67union_shape!(SocketAddrV6 => socket_v6_binary_shape());
68
69impl SerializeShape for IpAddr {
70 fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
71 let binary = context.define_named_type(TypeName::of::<Self>("IpAddr"), |_| {
72 SerializeDefinitionKind::Enum(SerializeEnumShape {
73 repr: Tagging::External,
74 variants: vec![
75 serialize_newtype_variant("V4", ipv4_binary_shape()),
76 serialize_newtype_variant("V6", ipv6_binary_shape()),
77 ],
78 attributes: serialize_enum_attributes(),
79 })
80 });
81 ShapeRef::union([ShapeRef::String, binary])
82 }
83}
84
85impl DeserializeShape for IpAddr {
86 fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
87 let binary = context.define_named_type(TypeName::of::<Self>("IpAddr"), |_| {
88 DeserializeDefinitionKind::Enum(DeserializeEnumShape {
89 repr: Tagging::External,
90 variants: vec![
91 deserialize_newtype_variant("V4", ipv4_binary_shape()),
92 deserialize_newtype_variant("V6", ipv6_binary_shape()),
93 ],
94 attributes: deserialize_enum_attributes(),
95 })
96 });
97 ShapeRef::union([ShapeRef::String, binary])
98 }
99}
100
101impl SerializeShape for SocketAddr {
102 fn serialize_shape_in(context: &mut SerializeShapeContext) -> ShapeRef {
103 let binary = context.define_named_type(TypeName::of::<Self>("SocketAddr"), |_| {
104 SerializeDefinitionKind::Enum(SerializeEnumShape {
105 repr: Tagging::External,
106 variants: vec![
107 serialize_newtype_variant("V4", socket_v4_binary_shape()),
108 serialize_newtype_variant("V6", socket_v6_binary_shape()),
109 ],
110 attributes: serialize_enum_attributes(),
111 })
112 });
113 ShapeRef::union([ShapeRef::String, binary])
114 }
115}
116
117impl DeserializeShape for SocketAddr {
118 fn deserialize_shape_in(context: &mut DeserializeShapeContext) -> ShapeRef {
119 let binary = context.define_named_type(TypeName::of::<Self>("SocketAddr"), |_| {
120 DeserializeDefinitionKind::Enum(DeserializeEnumShape {
121 repr: Tagging::External,
122 variants: vec![
123 deserialize_newtype_variant("V4", socket_v4_binary_shape()),
124 deserialize_newtype_variant("V6", socket_v6_binary_shape()),
125 ],
126 attributes: deserialize_enum_attributes(),
127 })
128 });
129 ShapeRef::union([ShapeRef::String, binary])
130 }
131}
132
133fn ipv4_binary_shape() -> ShapeRef {
134 ShapeRef::Array {
135 item: Box::new(ShapeRef::U8),
136 len: 4,
137 }
138}
139
140fn ipv6_binary_shape() -> ShapeRef {
141 ShapeRef::Array {
142 item: Box::new(ShapeRef::U8),
143 len: 16,
144 }
145}
146
147fn socket_v4_binary_shape() -> ShapeRef {
148 ShapeRef::Tuple(vec![ipv4_binary_shape(), ShapeRef::U16])
149}
150
151fn socket_v6_binary_shape() -> ShapeRef {
152 ShapeRef::Tuple(vec![ipv6_binary_shape(), ShapeRef::U16])
153}
154
155fn serialize_newtype_variant(name: &'static str, shape: ShapeRef) -> SerializeVariantShape {
156 SerializeVariantShape {
157 rust_name: name,
158 name,
159 description: None,
160 style: FieldsStyle::Newtype,
161 content: SerializeVariantContent::Fields(vec![SerializeFieldShape {
162 member: FieldMember::Unnamed(0),
163 name: "0",
164 description: None,
165 wire_shape: FieldWireShape::Value(shape),
166 skip_if: None,
167 }]),
168 untagged: false,
169 }
170}
171
172fn deserialize_newtype_variant(name: &'static str, shape: ShapeRef) -> DeserializeVariantShape {
173 DeserializeVariantShape {
174 rust_name: name,
175 name,
176 aliases: vec![name],
177 description: None,
178 style: FieldsStyle::Newtype,
179 content: DeserializeVariantContent::Fields(vec![DeserializeFieldShape {
180 member: FieldMember::Unnamed(0),
181 name: "0",
182 aliases: vec!["0"],
183 description: None,
184 wire_shape: FieldWireShape::Value(shape),
185 default: DefaultShape::None,
186 }]),
187 other: false,
188 untagged: false,
189 }
190}
191
192fn serialize_enum_attributes() -> SerializeContainerAttributes {
193 SerializeContainerAttributes::default()
194}
195
196fn deserialize_enum_attributes() -> DeserializeContainerAttributes {
197 DeserializeContainerAttributes::default()
198}