Skip to main content

csv/
serde.rs

1#![cfg(feature = "serde")]
2
3extern crate alloc;
4
5use alloc::{
6    borrow::ToOwned,
7    collections::BTreeMap,
8    string::{String, ToString},
9    vec::Vec,
10};
11use core::fmt;
12
13use serde::{
14    de::{self, DeserializeSeed, Deserializer, Error as _, SeqAccess, Visitor},
15    ser,
16};
17
18use crate::{
19    error::{ReadError, ReadErrorKind, WriteError},
20    reader::{FieldRange, Row},
21    writer::{Write, Writer, write_csv_field},
22};
23
24impl Row {
25    /// Deserialize this row into a `T`.
26    ///
27    /// Headers must have been set on the parent [`Reader`](crate::Reader)
28    /// via [`parse_headers`](crate::Reader::parse_headers) or
29    /// [`set_headers`](crate::Reader::set_headers) before calling this method.
30    /// Struct fields are matched by column name.
31    ///
32    /// # Errors
33    ///
34    /// Returns [`ReadError`] with kind [`Deserialize`](crate::ReadErrorKind::Deserialize)
35    /// if headers have not been set, or if deserialization fails (type mismatch,
36    /// unknown field, etc.).
37    ///
38    /// # Example
39    ///
40    /// ```no_run
41    /// use csv::Reader;
42    /// use serde::Deserialize;
43    ///
44    /// #[derive(Deserialize)]
45    /// struct Record { name: String, age: u32 }
46    ///
47    /// let mut reader = Reader::new(std::io::Cursor::new(b"name,age\nAlice,30\n"));
48    /// reader.parse_headers()?;
49    /// for row in reader.rows() {
50    ///     let rec: Record = row.deserialize()?;
51    ///     println!("{} is {}", rec.name, rec.age);
52    /// }
53    /// # Ok::<_, Box<dyn std::error::Error>>(())
54    /// ```
55    pub fn deserialize<T>(&self) -> Result<T, ReadError>
56    where
57        T: serde::de::DeserializeOwned,
58    {
59        if self.inner.error.is_some() {
60            return Err(self.inner.error.clone().unwrap());
61        }
62
63        let header_map = self
64            .header_map
65            .as_ref()
66            .ok_or_else(|| ReadError::new(ReadErrorKind::Deserialize("headers not set".into()), 0, 0))?;
67        let mut deser = HeaderRow {
68            buf: &self.inner.buf,
69            ranges: &self.inner.ranges,
70            header_map,
71            struct_fields: &[],
72            index: 0,
73        };
74        T::deserialize(&mut deser).map_err(|e| ReadError::new(ReadErrorKind::Deserialize(e.msg), 0, 0))
75    }
76}
77
78struct HeaderRow<'de> {
79    buf: &'de [u8],
80    ranges: &'de [FieldRange],
81    header_map: &'de BTreeMap<String, usize>,
82    struct_fields: &'static [&'static str],
83    index: usize,
84}
85
86impl<'de> HeaderRow<'de> {
87    fn field(&self, idx: usize) -> Result<&'de str, CsvError> {
88        let range = self
89            .ranges
90            .get(idx)
91            .ok_or_else(|| CsvError::custom("field index out of bounds"))?;
92        core::str::from_utf8(&self.buf[range.start..range.end]).map_err(|_| CsvError::custom("invalid UTF-8 in field"))
93    }
94}
95
96impl<'de> Deserializer<'de> for &mut HeaderRow<'de> {
97    type Error = CsvError;
98
99    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
100    where
101        V: Visitor<'de>,
102    {
103        self.deserialize_struct("", &[], visitor)
104    }
105
106    fn deserialize_struct<V>(
107        mut self,
108        _name: &'static str,
109        struct_fields: &'static [&'static str],
110        visitor: V,
111    ) -> Result<V::Value, Self::Error>
112    where
113        V: Visitor<'de>,
114    {
115        self.struct_fields = struct_fields;
116        self.index = 0;
117        visitor.visit_seq(&mut self)
118    }
119
120    serde::forward_to_deserialize_any! {
121        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
122        bytes byte_buf option unit unit_struct newtype_struct seq tuple
123        tuple_struct map enum identifier ignored_any
124    }
125}
126
127impl<'de> SeqAccess<'de> for HeaderRow<'de> {
128    type Error = CsvError;
129
130    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
131    where
132        T: DeserializeSeed<'de>,
133    {
134        if self.index >= self.struct_fields.len() {
135            return Ok(None);
136        }
137        let field_name = self.struct_fields[self.index];
138        self.index += 1;
139        let val = match self.header_map.get(field_name) {
140            Some(&idx) => self.field(idx).unwrap_or(""),
141            None => "",
142        };
143        seed.deserialize(FieldDeserializer(val)).map(Some)
144    }
145}
146
147/// Deserializes a single CSV field value with proper type coercion.
148struct FieldDeserializer<'a>(&'a str);
149
150macro_rules! forward_parse {
151    ($($method:ident => $visit:ident :: $ty:ty),*) => {
152        $(
153            fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
154            where V: Visitor<'de>,
155            {
156                let v: $ty = self.0.parse().map_err(|_| {
157                    CsvError::custom(concat!("invalid ", stringify!($ty)))
158                })?;
159                visitor.$visit(v)
160            }
161        )*
162    };
163}
164
165impl<'de, 'a: 'de> Deserializer<'de> for FieldDeserializer<'a> {
166    type Error = CsvError;
167
168    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
169    where
170        V: Visitor<'de>,
171    {
172        visitor.visit_borrowed_str(self.0)
173    }
174
175    forward_parse! {
176        deserialize_bool   => visit_bool   :: bool,
177        deserialize_i8     => visit_i8     :: i8,
178        deserialize_i16    => visit_i16    :: i16,
179        deserialize_i32    => visit_i32    :: i32,
180        deserialize_i64    => visit_i64    :: i64,
181        deserialize_i128   => visit_i128   :: i128,
182        deserialize_u8     => visit_u8     :: u8,
183        deserialize_u16    => visit_u16    :: u16,
184        deserialize_u32    => visit_u32    :: u32,
185        deserialize_u64    => visit_u64    :: u64,
186        deserialize_u128   => visit_u128   :: u128,
187        deserialize_f32    => visit_f32    :: f32,
188        deserialize_f64    => visit_f64    :: f64
189    }
190
191    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
192    where
193        V: Visitor<'de>,
194    {
195        let mut chars = self.0.chars();
196        let ch = chars.next().ok_or_else(|| CsvError::custom("empty char"))?;
197        if chars.next().is_some() {
198            return Err(CsvError::custom("char field contains more than one character"));
199        }
200        visitor.visit_char(ch)
201    }
202
203    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
204    where
205        V: Visitor<'de>,
206    {
207        visitor.visit_borrowed_str(self.0)
208    }
209
210    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
211    where
212        V: Visitor<'de>,
213    {
214        visitor.visit_string(self.0.to_owned())
215    }
216
217    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
218    where
219        V: Visitor<'de>,
220    {
221        visitor.visit_borrowed_bytes(self.0.as_bytes())
222    }
223
224    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
225    where
226        V: Visitor<'de>,
227    {
228        visitor.visit_byte_buf(self.0.as_bytes().to_vec())
229    }
230
231    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
232    where
233        V: Visitor<'de>,
234    {
235        if self.0.is_empty() {
236            visitor.visit_none()
237        } else {
238            visitor.visit_some(self)
239        }
240    }
241
242    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
243    where
244        V: Visitor<'de>,
245    {
246        visitor.visit_unit()
247    }
248
249    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
250    where
251        V: Visitor<'de>,
252    {
253        visitor.visit_unit()
254    }
255
256    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
257    where
258        V: Visitor<'de>,
259    {
260        visitor.visit_newtype_struct(self)
261    }
262
263    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
264    where
265        V: Visitor<'de>,
266    {
267        Err(CsvError::custom("cannot deserialize sequence from a single field"))
268    }
269
270    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
271    where
272        V: Visitor<'de>,
273    {
274        Err(CsvError::custom("cannot deserialize tuple from a single field"))
275    }
276
277    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
278    where
279        V: Visitor<'de>,
280    {
281        Err(CsvError::custom("cannot deserialize tuple struct from a single field"))
282    }
283
284    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
285    where
286        V: Visitor<'de>,
287    {
288        Err(CsvError::custom("cannot deserialize map from a single field"))
289    }
290
291    fn deserialize_struct<V>(
292        self,
293        _name: &'static str,
294        _fields: &'static [&'static str],
295        _visitor: V,
296    ) -> Result<V::Value, Self::Error>
297    where
298        V: Visitor<'de>,
299    {
300        Err(CsvError::custom("cannot deserialize struct from a single field"))
301    }
302
303    fn deserialize_enum<V>(
304        self,
305        _name: &'static str,
306        _variants: &'static [&'static str],
307        _visitor: V,
308    ) -> Result<V::Value, Self::Error>
309    where
310        V: Visitor<'de>,
311    {
312        Err(CsvError::custom("cannot deserialize enum from a single field"))
313    }
314
315    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
316    where
317        V: Visitor<'de>,
318    {
319        visitor.visit_borrowed_str(self.0)
320    }
321
322    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
323    where
324        V: Visitor<'de>,
325    {
326        visitor.visit_unit()
327    }
328}
329
330#[derive(Debug)]
331pub struct CsvError {
332    pub(crate) msg: String,
333}
334
335impl de::Error for CsvError {
336    fn custom<T: fmt::Display>(msg: T) -> Self {
337        CsvError {
338            msg: msg.to_string(),
339        }
340    }
341}
342
343impl ser::Error for CsvError {
344    fn custom<T: fmt::Display>(msg: T) -> Self {
345        CsvError {
346            msg: msg.to_string(),
347        }
348    }
349}
350
351impl fmt::Display for CsvError {
352    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353        write!(f, "{}", self.msg)
354    }
355}
356
357#[cfg(feature = "std")]
358impl std::error::Error for CsvError {}
359
360#[cfg(all(not(feature = "std"), feature = "serde"))]
361impl core::error::Error for CsvError {}
362
363// ── Serialization ─────────────────────────────────────────────────────
364
365impl<W: Write> Writer<W> {
366    /// Serialize a record and write it as a CSV data row.
367    ///
368    /// Headers must have been set (via [`set_headers`](Self::set_headers) or
369    /// [`write_headers`](Self::write_headers)) before calling this method.
370    ///
371    /// For structs, fields are matched by name against the stored headers and
372    /// written in header column order. For sequences and tuples, elements are
373    /// written positionally (the field count must equal the header count).
374    ///
375    /// # Errors
376    ///
377    /// Returns [`WriteError::Serialize`] if headers have not been set, or if
378    /// a serde serialization error occurs (e.g. an unknown field name, or an
379    /// unsupported type like a map or enum).
380    ///
381    /// Returns [`WriteError::InconsistentFieldCount`] if the number of fields
382    /// serialized differs from the expected count (unless flexible mode is
383    /// enabled).
384    ///
385    /// Returns [`WriteError::Io`] if the underlying writer fails on flush.
386    ///
387    /// # Example
388    ///
389    /// ```no_run
390    /// use csv::Writer;
391    /// use serde::Serialize;
392    ///
393    /// #[derive(Serialize)]
394    /// struct Person {
395    ///     name: String,
396    ///     age: u32,
397    /// }
398    ///
399    /// let mut w = Writer::new(Vec::new())
400    ///     .set_headers(vec!["name".into(), "age".into()]);
401    ///
402    /// let alice = Person { name: "Alice".into(), age: 30 };
403    /// w.serialize(&alice)?;
404    /// let result = String::from_utf8(w.into_inner()?).unwrap();
405    /// assert_eq!(result, "Alice,30\r\n");
406    /// # Ok::<_, csv::WriteError>(())
407    /// ```
408    pub fn serialize<T: serde::Serialize>(&mut self, record: &T) -> Result<(), WriteError> {
409        if self.headers.is_none() {
410            return Err(WriteError::Serialize("headers not set".into()));
411        }
412        let headers = self.headers.as_ref().unwrap();
413        let header_count = headers.len();
414        let delimiter = self.delimiter;
415
416        self.ser_values.clear();
417        self.ser_values.resize_with(header_count, || None);
418        self.ser_capture_buf.clear();
419        let mut field_count = 0;
420
421        {
422            let mut ser = StructSer {
423                headers,
424                values: &mut self.ser_values,
425                field_count: &mut field_count,
426                capture_buf: &mut self.ser_capture_buf,
427            };
428            record.serialize(&mut ser).map_err(|e| WriteError::Serialize(e.msg))?;
429        }
430
431        match self.num_fields {
432            Some(expected) if !self.flexible && header_count != expected => {
433                return Err(WriteError::InconsistentFieldCount {
434                    expected,
435                    found: header_count,
436                    row: self.row_count + 1,
437                });
438            }
439            None => {
440                self.num_fields = Some(header_count);
441            }
442            _ => {}
443        }
444
445        for (i, val) in self.ser_values.iter().enumerate() {
446            if i > 0 {
447                self.buf.push(delimiter);
448            }
449            match val {
450                Some(field) => write_csv_field(&mut self.buf, delimiter, field),
451                None => write_csv_field(&mut self.buf, delimiter, b""),
452            }
453        }
454        self.buf.extend_from_slice(b"\r\n");
455        self.row_count += 1;
456
457        if self.buf.len() >= 8192 {
458            self.flush()?;
459        }
460
461        Ok(())
462    }
463}
464
465/// Top-level serializer that collects field values from a serde record.
466struct StructSer<'a, 'b> {
467    headers: &'a [String],
468    values: &'b mut Vec<Option<Vec<u8>>>,
469    field_count: &'b mut usize,
470    capture_buf: &'b mut Vec<u8>,
471}
472
473impl<'a, 'b> serde::Serializer for &'b mut StructSer<'a, 'b> {
474    type Ok = ();
475    type Error = CsvError;
476
477    type SerializeSeq = SeqWriter<'b>;
478    type SerializeTuple = SeqWriter<'b>;
479    type SerializeTupleStruct = SeqWriter<'b>;
480    type SerializeTupleVariant = serde::ser::Impossible<(), CsvError>;
481    type SerializeMap = serde::ser::Impossible<(), CsvError>;
482    type SerializeStruct = StructCollector<'a, 'b>;
483    type SerializeStructVariant = serde::ser::Impossible<(), CsvError>;
484
485    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<StructCollector<'a, 'b>, CsvError> {
486        Ok(StructCollector {
487            headers: self.headers,
488            values: self.values,
489            field_count: self.field_count,
490            capture_buf: self.capture_buf,
491        })
492    }
493
494    fn serialize_seq(self, _len: Option<usize>) -> Result<SeqWriter<'b>, CsvError> {
495        Ok(SeqWriter {
496            values: self.values,
497            field_count: self.field_count,
498            idx: 0,
499            capture_buf: self.capture_buf,
500        })
501    }
502
503    fn serialize_tuple(self, _len: usize) -> Result<SeqWriter<'b>, CsvError> {
504        self.serialize_seq(Some(_len))
505    }
506
507    fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<SeqWriter<'b>, CsvError> {
508        self.serialize_seq(Some(_len))
509    }
510
511    fn serialize_bool(self, v: bool) -> Result<(), CsvError> {
512        let s = if v { "true" } else { "false" };
513        self.serialize_str(s)
514    }
515
516    fn serialize_i8(self, v: i8) -> Result<(), CsvError> {
517        let mut buf = itoa::Buffer::new();
518        self.serialize_str(buf.format(v))
519    }
520    fn serialize_i16(self, v: i16) -> Result<(), CsvError> {
521        let mut buf = itoa::Buffer::new();
522        self.serialize_str(buf.format(v))
523    }
524    fn serialize_i32(self, v: i32) -> Result<(), CsvError> {
525        let mut buf = itoa::Buffer::new();
526        self.serialize_str(buf.format(v))
527    }
528    fn serialize_i64(self, v: i64) -> Result<(), CsvError> {
529        let mut buf = itoa::Buffer::new();
530        self.serialize_str(buf.format(v))
531    }
532    fn serialize_i128(self, v: i128) -> Result<(), CsvError> {
533        let mut buf = itoa::Buffer::new();
534        self.serialize_str(buf.format(v))
535    }
536    fn serialize_u8(self, v: u8) -> Result<(), CsvError> {
537        let mut buf = itoa::Buffer::new();
538        self.serialize_str(buf.format(v))
539    }
540    fn serialize_u16(self, v: u16) -> Result<(), CsvError> {
541        let mut buf = itoa::Buffer::new();
542        self.serialize_str(buf.format(v))
543    }
544    fn serialize_u32(self, v: u32) -> Result<(), CsvError> {
545        let mut buf = itoa::Buffer::new();
546        self.serialize_str(buf.format(v))
547    }
548    fn serialize_u64(self, v: u64) -> Result<(), CsvError> {
549        let mut buf = itoa::Buffer::new();
550        self.serialize_str(buf.format(v))
551    }
552    fn serialize_u128(self, v: u128) -> Result<(), CsvError> {
553        let mut buf = itoa::Buffer::new();
554        self.serialize_str(buf.format(v))
555    }
556    fn serialize_f32(self, v: f32) -> Result<(), CsvError> {
557        let mut buf = ryu::Buffer::new();
558        self.serialize_str(buf.format(v))
559    }
560    fn serialize_f64(self, v: f64) -> Result<(), CsvError> {
561        let mut buf = ryu::Buffer::new();
562        self.serialize_str(buf.format(v))
563    }
564
565    fn serialize_char(self, v: char) -> Result<(), CsvError> {
566        let mut buf = [0u8; 4];
567        let s = v.encode_utf8(&mut buf);
568        self.serialize_str(s)
569    }
570
571    fn serialize_str(self, v: &str) -> Result<(), CsvError> {
572        self.write_field_bytes(v.as_bytes());
573        Ok(())
574    }
575
576    fn serialize_bytes(self, v: &[u8]) -> Result<(), CsvError> {
577        self.write_field_bytes(v);
578        Ok(())
579    }
580
581    fn serialize_none(self) -> Result<(), CsvError> {
582        self.write_field_bytes(b"");
583        Ok(())
584    }
585
586    fn serialize_some<T: ?Sized + serde::Serialize>(self, value: &T) -> Result<(), CsvError> {
587        value.serialize(self)
588    }
589
590    fn serialize_unit(self) -> Result<(), CsvError> {
591        self.write_field_bytes(b"");
592        Ok(())
593    }
594
595    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), CsvError> {
596        self.write_field_bytes(b"");
597        Ok(())
598    }
599
600    fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(
601        self,
602        _name: &'static str,
603        value: &T,
604    ) -> Result<(), CsvError> {
605        value.serialize(self)
606    }
607
608    fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
609        self,
610        _name: &'static str,
611        _idx: u32,
612        _variant: &'static str,
613        _value: &T,
614    ) -> Result<(), CsvError> {
615        Err(CsvError::custom("enum variants not supported"))
616    }
617
618    fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result<(), CsvError> {
619        Err(CsvError::custom("enum variants not supported"))
620    }
621
622    fn serialize_tuple_variant(
623        self,
624        _name: &'static str,
625        _idx: u32,
626        _variant: &'static str,
627        _len: usize,
628    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
629        Err(CsvError::custom("enum variants not supported"))
630    }
631
632    fn serialize_struct_variant(
633        self,
634        _name: &'static str,
635        _idx: u32,
636        _variant: &'static str,
637        _len: usize,
638    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
639        Err(CsvError::custom("enum variants not supported"))
640    }
641
642    fn serialize_map(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
643        Err(CsvError::custom("maps not supported"))
644    }
645}
646
647impl StructSer<'_, '_> {
648    fn write_field_bytes(&mut self, bytes: &[u8]) {
649        if let Some(slot) = self.values.first_mut() {
650            *slot = Some(bytes.to_vec());
651        }
652        *self.field_count = 1;
653    }
654}
655
656/// Collects struct fields by name and stores them at header-matching positions.
657struct StructCollector<'a, 'b> {
658    headers: &'a [String],
659    values: &'b mut Vec<Option<Vec<u8>>>,
660    field_count: &'b mut usize,
661    capture_buf: &'b mut Vec<u8>,
662}
663
664impl ser::SerializeStruct for StructCollector<'_, '_> {
665    type Ok = ();
666    type Error = CsvError;
667
668    fn serialize_field<T: ?Sized + serde::Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), CsvError> {
669        let pos = self
670            .headers
671            .iter()
672            .position(|h| h == key)
673            .ok_or_else(|| CsvError::custom(alloc::format!("unknown field '{key}'")))?;
674
675        self.capture_buf.clear();
676        {
677            let mut capture = FieldCapture {
678                buf: self.capture_buf,
679            };
680            value.serialize(&mut capture)?;
681        }
682        self.values[pos] = Some(core::mem::take(self.capture_buf));
683        *self.field_count += 1;
684        Ok(())
685    }
686
687    fn end(self) -> Result<(), CsvError> {
688        Ok(())
689    }
690}
691
692/// Writes seq/tuple elements positionally into the values array.
693struct SeqWriter<'b> {
694    values: &'b mut Vec<Option<Vec<u8>>>,
695    field_count: &'b mut usize,
696    idx: usize,
697    capture_buf: &'b mut Vec<u8>,
698}
699
700impl ser::SerializeSeq for SeqWriter<'_> {
701    type Ok = ();
702    type Error = CsvError;
703
704    fn serialize_element<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
705        if self.idx >= self.values.len() {
706            return Err(CsvError::custom("sequence longer than header count"));
707        }
708        self.capture_buf.clear();
709        {
710            let mut capture = FieldCapture {
711                buf: self.capture_buf,
712            };
713            value.serialize(&mut capture)?;
714        }
715        self.values[self.idx] = Some(core::mem::take(self.capture_buf));
716        self.idx += 1;
717        *self.field_count += 1;
718        Ok(())
719    }
720
721    fn end(self) -> Result<(), CsvError> {
722        if self.idx != self.values.len() {
723            return Err(CsvError::custom("sequence length does not match header count"));
724        }
725        Ok(())
726    }
727}
728
729impl ser::SerializeTuple for SeqWriter<'_> {
730    type Ok = ();
731    type Error = CsvError;
732
733    fn serialize_element<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
734        ser::SerializeSeq::serialize_element(self, value)
735    }
736
737    fn end(self) -> Result<(), CsvError> {
738        ser::SerializeSeq::end(self)
739    }
740}
741
742impl ser::SerializeTupleStruct for SeqWriter<'_> {
743    type Ok = ();
744    type Error = CsvError;
745
746    fn serialize_field<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
747        ser::SerializeSeq::serialize_element(self, value)
748    }
749
750    fn end(self) -> Result<(), CsvError> {
751        ser::SerializeSeq::end(self)
752    }
753}
754
755/// Captures a single serialized field value into a `Vec<u8>`.
756struct FieldCapture<'a> {
757    buf: &'a mut Vec<u8>,
758}
759
760impl<'a> serde::Serializer for &'a mut FieldCapture<'a> {
761    type Ok = ();
762    type Error = CsvError;
763
764    type SerializeSeq = serde::ser::Impossible<(), CsvError>;
765    type SerializeTuple = serde::ser::Impossible<(), CsvError>;
766    type SerializeTupleStruct = serde::ser::Impossible<(), CsvError>;
767    type SerializeTupleVariant = serde::ser::Impossible<(), CsvError>;
768    type SerializeMap = serde::ser::Impossible<(), CsvError>;
769    type SerializeStruct = serde::ser::Impossible<(), CsvError>;
770    type SerializeStructVariant = serde::ser::Impossible<(), CsvError>;
771
772    fn serialize_bool(self, v: bool) -> Result<(), CsvError> {
773        let s = if v { "true" } else { "false" };
774        self.buf.extend_from_slice(s.as_bytes());
775        Ok(())
776    }
777
778    fn serialize_i8(self, v: i8) -> Result<(), CsvError> {
779        let mut buf = itoa::Buffer::new();
780        self.serialize_str(buf.format(v))
781    }
782    fn serialize_i16(self, v: i16) -> Result<(), CsvError> {
783        let mut buf = itoa::Buffer::new();
784        self.serialize_str(buf.format(v))
785    }
786    fn serialize_i32(self, v: i32) -> Result<(), CsvError> {
787        let mut buf = itoa::Buffer::new();
788        self.serialize_str(buf.format(v))
789    }
790    fn serialize_i64(self, v: i64) -> Result<(), CsvError> {
791        let mut buf = itoa::Buffer::new();
792        self.serialize_str(buf.format(v))
793    }
794    fn serialize_i128(self, v: i128) -> Result<(), CsvError> {
795        let mut buf = itoa::Buffer::new();
796        self.serialize_str(buf.format(v))
797    }
798    fn serialize_u8(self, v: u8) -> Result<(), CsvError> {
799        let mut buf = itoa::Buffer::new();
800        self.serialize_str(buf.format(v))
801    }
802    fn serialize_u16(self, v: u16) -> Result<(), CsvError> {
803        let mut buf = itoa::Buffer::new();
804        self.serialize_str(buf.format(v))
805    }
806    fn serialize_u32(self, v: u32) -> Result<(), CsvError> {
807        let mut buf = itoa::Buffer::new();
808        self.serialize_str(buf.format(v))
809    }
810    fn serialize_u64(self, v: u64) -> Result<(), CsvError> {
811        let mut buf = itoa::Buffer::new();
812        self.serialize_str(buf.format(v))
813    }
814    fn serialize_u128(self, v: u128) -> Result<(), CsvError> {
815        let mut buf = itoa::Buffer::new();
816        self.serialize_str(buf.format(v))
817    }
818    fn serialize_f32(self, v: f32) -> Result<(), CsvError> {
819        let mut buf = ryu::Buffer::new();
820        self.serialize_str(buf.format(v))
821    }
822    fn serialize_f64(self, v: f64) -> Result<(), CsvError> {
823        let mut buf = ryu::Buffer::new();
824        self.serialize_str(buf.format(v))
825    }
826
827    fn serialize_char(self, v: char) -> Result<(), CsvError> {
828        let mut buf = [0u8; 4];
829        let s = v.encode_utf8(&mut buf);
830        self.buf.extend_from_slice(s.as_bytes());
831        Ok(())
832    }
833
834    fn serialize_str(self, v: &str) -> Result<(), CsvError> {
835        self.buf.extend_from_slice(v.as_bytes());
836        Ok(())
837    }
838
839    fn serialize_bytes(self, v: &[u8]) -> Result<(), CsvError> {
840        self.buf.extend_from_slice(v);
841        Ok(())
842    }
843
844    fn serialize_none(self) -> Result<(), CsvError> {
845        Ok(())
846    }
847
848    fn serialize_some<T: ?Sized + serde::Serialize>(self, value: &T) -> Result<(), CsvError> {
849        value.serialize(self)
850    }
851
852    fn serialize_unit(self) -> Result<(), CsvError> {
853        Ok(())
854    }
855
856    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), CsvError> {
857        Ok(())
858    }
859
860    fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(
861        self,
862        _name: &'static str,
863        value: &T,
864    ) -> Result<(), CsvError> {
865        value.serialize(self)
866    }
867
868    fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
869        self,
870        _name: &'static str,
871        _idx: u32,
872        _variant: &'static str,
873        _value: &T,
874    ) -> Result<(), CsvError> {
875        Err(CsvError::custom("enum variants not supported in field capture"))
876    }
877
878    fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result<(), CsvError> {
879        Err(CsvError::custom("enum variants not supported in field capture"))
880    }
881
882    fn serialize_tuple_variant(
883        self,
884        _name: &'static str,
885        _idx: u32,
886        _variant: &'static str,
887        _len: usize,
888    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
889        Err(CsvError::custom("enum variants not supported in field capture"))
890    }
891
892    fn serialize_struct_variant(
893        self,
894        _name: &'static str,
895        _idx: u32,
896        _variant: &'static str,
897        _len: usize,
898    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
899        Err(CsvError::custom("enum variants not supported in field capture"))
900    }
901
902    fn serialize_seq(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
903        Err(CsvError::custom("sequence inside a single field not supported"))
904    }
905
906    fn serialize_tuple(self, _len: usize) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
907        Err(CsvError::custom("tuple inside a single field not supported"))
908    }
909
910    fn serialize_tuple_struct(
911        self,
912        _name: &'static str,
913        _len: usize,
914    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
915        Err(CsvError::custom("tuple struct inside a single field not supported"))
916    }
917
918    fn serialize_map(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
919        Err(CsvError::custom("map inside a single field not supported"))
920    }
921
922    fn serialize_struct(
923        self,
924        _name: &'static str,
925        _len: usize,
926    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
927        Err(CsvError::custom("struct inside a single field not supported"))
928    }
929}