1use std::{borrow::Borrow, io::Write};
19
20use serde::{
21 Serialize,
22 ser::{SerializeTuple, SerializeTupleStruct, SerializeTupleVariant},
23};
24
25use super::{Config, SchemaAwareSerializer, union::UnionSerializer};
26use crate::{
27 Error, Schema,
28 error::Details,
29 schema::{RecordSchema, UnionSchema},
30};
31
32#[expect(
33 private_interfaces,
34 reason = "One{,Union}TupleSerializer should not be used directly"
35)]
36pub enum TupleSerializer<'s, 'w, W: Write, S: Borrow<Schema>> {
37 Unit(usize),
38 One(OneTupleSerializer<'s, 'w, W, S>),
39 OneUnion(OneUnionTupleSerializer<'s, 'w, W, S>),
41 Many(ManyTupleSerializer<'s, 'w, W, S>),
42}
43
44impl<'s, 'w, W: Write, S: Borrow<Schema>> TupleSerializer<'s, 'w, W, S> {
45 pub fn unit(bytes_written: Option<usize>) -> Self {
46 Self::Unit(bytes_written.unwrap_or(0))
47 }
48
49 pub fn one(
50 writer: &'w mut W,
51 schema: &'s Schema,
52 config: Config<'s, S>,
53 bytes_written: Option<usize>,
54 ) -> Self {
55 Self::One(OneTupleSerializer::new(
56 writer,
57 schema,
58 config,
59 bytes_written,
60 ))
61 }
62
63 pub fn one_union(writer: &'w mut W, union: &'s UnionSchema, config: Config<'s, S>) -> Self {
64 Self::OneUnion(OneUnionTupleSerializer::new(writer, union, config))
65 }
66
67 pub fn many(
68 writer: &'w mut W,
69 schema: &'s RecordSchema,
70 config: Config<'s, S>,
71 bytes_written: Option<usize>,
72 ) -> Self {
73 Self::Many(ManyTupleSerializer::new(
74 writer,
75 schema,
76 config,
77 bytes_written,
78 ))
79 }
80}
81
82impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTuple for TupleSerializer<'s, 'w, W, S> {
83 type Ok = usize;
84 type Error = Error;
85
86 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
87 where
88 T: ?Sized + Serialize,
89 {
90 match self {
91 TupleSerializer::Unit(_) => Err(Error::new(Details::SerializeValueWithSchema {
92 value_type: "tuple",
93 value: "Expected no elements for the unit tuple".into(),
94 schema: Schema::Null,
95 })),
96 TupleSerializer::One(one) => one.serialize_element(value),
97 TupleSerializer::OneUnion(one) => one.serialize_element(value),
98 TupleSerializer::Many(many) => many.serialize_element(value),
99 }
100 }
101
102 fn end(self) -> Result<Self::Ok, Self::Error> {
103 match self {
104 TupleSerializer::Unit(bytes_written) => Ok(bytes_written),
105 TupleSerializer::One(one) => one.end(),
106 TupleSerializer::OneUnion(one) => one.end(),
107 TupleSerializer::Many(many) => SerializeTuple::end(many),
108 }
109 }
110}
111
112pub struct ManyTupleSerializer<'s, 'w, W: Write, S: Borrow<Schema>> {
113 writer: &'w mut W,
114 schema: &'s RecordSchema,
115 config: Config<'s, S>,
116 field_position: usize,
117 bytes_written: usize,
118}
119
120impl<'s, 'w, W: Write, S: Borrow<Schema>> ManyTupleSerializer<'s, 'w, W, S> {
121 pub fn new(
122 writer: &'w mut W,
123 schema: &'s RecordSchema,
124 config: Config<'s, S>,
125 bytes_written: Option<usize>,
126 ) -> Self {
127 Self {
128 writer,
129 schema,
130 config,
131 field_position: 0,
132 bytes_written: bytes_written.unwrap_or(0),
133 }
134 }
135}
136
137impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTuple for ManyTupleSerializer<'s, 'w, W, S> {
138 type Ok = usize;
139 type Error = Error;
140
141 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
142 where
143 T: ?Sized + Serialize,
144 {
145 let schema = &self
146 .schema
147 .fields
148 .get(self.field_position)
149 .ok_or_else(|| Details::SerializeRecordUnknownFieldIndex {
150 position: self.field_position,
151 schema: self.schema.clone(),
152 })?
153 .schema;
154 self.bytes_written += value.serialize(SchemaAwareSerializer::new(
155 self.writer,
156 schema,
157 self.config,
158 )?)?;
159 self.field_position += 1;
160 Ok(())
161 }
162
163 fn end(self) -> Result<Self::Ok, Self::Error> {
164 if self.field_position != self.schema.fields.len() {
165 Err(Details::SerializeTupleMissingElements {
166 position: self.field_position,
167 total_elements: self.schema.fields.len(),
168 }
169 .into())
170 } else {
171 Ok(self.bytes_written)
172 }
173 }
174}
175
176impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTupleStruct
177 for ManyTupleSerializer<'s, 'w, W, S>
178{
179 type Ok = usize;
180 type Error = Error;
181
182 fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
183 where
184 T: ?Sized + Serialize,
185 {
186 SerializeTuple::serialize_element(self, value)
187 }
188
189 fn end(self) -> Result<Self::Ok, Self::Error> {
190 SerializeTuple::end(self)
191 }
192}
193
194impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTupleVariant
195 for ManyTupleSerializer<'s, 'w, W, S>
196{
197 type Ok = usize;
198 type Error = Error;
199
200 fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
201 where
202 T: ?Sized + Serialize,
203 {
204 SerializeTuple::serialize_element(self, value)
205 }
206
207 fn end(self) -> Result<Self::Ok, Self::Error> {
208 SerializeTuple::end(self)
209 }
210}
211
212struct OneTupleSerializer<'s, 'w, W: Write, S: Borrow<Schema>> {
213 writer: &'w mut W,
214 schema: &'s Schema,
215 config: Config<'s, S>,
216 bytes_written: usize,
217}
218
219impl<'s, 'w, W: Write, S: Borrow<Schema>> OneTupleSerializer<'s, 'w, W, S> {
220 pub fn new(
221 writer: &'w mut W,
222 schema: &'s Schema,
223 config: Config<'s, S>,
224 bytes_written: Option<usize>,
225 ) -> Self {
226 Self {
227 writer,
228 schema,
229 config,
230 bytes_written: bytes_written.unwrap_or(0),
231 }
232 }
233}
234
235impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTuple for OneTupleSerializer<'s, 'w, W, S> {
236 type Ok = usize;
237 type Error = Error;
238
239 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
240 where
241 T: ?Sized + Serialize,
242 {
243 match self.schema {
244 Schema::Union(union) => {
245 self.bytes_written +=
246 value.serialize(UnionSerializer::new(self.writer, union, self.config))?;
247 }
248 schema => {
249 self.bytes_written += value.serialize(SchemaAwareSerializer::new(
250 self.writer,
251 schema,
252 self.config,
253 )?)?;
254 }
255 }
256 Ok(())
257 }
258
259 fn end(self) -> Result<Self::Ok, Self::Error> {
260 Ok(self.bytes_written)
261 }
262}
263
264struct OneUnionTupleSerializer<'s, 'w, W: Write, S: Borrow<Schema>> {
265 writer: &'w mut W,
266 union: &'s UnionSchema,
267 config: Config<'s, S>,
268 bytes_written: usize,
269}
270
271impl<'s, 'w, W: Write, S: Borrow<Schema>> OneUnionTupleSerializer<'s, 'w, W, S> {
272 pub fn new(writer: &'w mut W, union: &'s UnionSchema, config: Config<'s, S>) -> Self {
273 Self {
274 writer,
275 union,
276 config,
277 bytes_written: 0,
278 }
279 }
280}
281
282impl<'s, 'w, W: Write, S: Borrow<Schema>> SerializeTuple for OneUnionTupleSerializer<'s, 'w, W, S> {
283 type Ok = usize;
284 type Error = Error;
285
286 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
287 where
288 T: ?Sized + Serialize,
289 {
290 self.bytes_written +=
291 value.serialize(UnionSerializer::new(self.writer, self.union, self.config))?;
292 Ok(())
293 }
294
295 fn end(self) -> Result<Self::Ok, Self::Error> {
296 Ok(self.bytes_written)
297 }
298}