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