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        self.serialize_str(&format_number::format_int(v))
518    }
519    fn serialize_i16(self, v: i16) -> Result<(), CsvError> {
520        self.serialize_str(&format_number::format_int(v))
521    }
522    fn serialize_i32(self, v: i32) -> Result<(), CsvError> {
523        self.serialize_str(&format_number::format_int(v))
524    }
525    fn serialize_i64(self, v: i64) -> Result<(), CsvError> {
526        self.serialize_str(&format_number::format_int(v))
527    }
528    fn serialize_i128(self, v: i128) -> Result<(), CsvError> {
529        self.serialize_str(&format_number::format_int(v))
530    }
531    fn serialize_u8(self, v: u8) -> Result<(), CsvError> {
532        self.serialize_str(&format_number::format_int(v))
533    }
534    fn serialize_u16(self, v: u16) -> Result<(), CsvError> {
535        self.serialize_str(&format_number::format_int(v))
536    }
537    fn serialize_u32(self, v: u32) -> Result<(), CsvError> {
538        self.serialize_str(&format_number::format_int(v))
539    }
540    fn serialize_u64(self, v: u64) -> Result<(), CsvError> {
541        self.serialize_str(&format_number::format_int(v))
542    }
543    fn serialize_u128(self, v: u128) -> Result<(), CsvError> {
544        self.serialize_str(&format_number::format_int(v))
545    }
546    fn serialize_f32(self, v: f32) -> Result<(), CsvError> {
547        let mut buf = ryu::Buffer::new();
548        self.serialize_str(buf.format(v))
549    }
550    fn serialize_f64(self, v: f64) -> Result<(), CsvError> {
551        let mut buf = ryu::Buffer::new();
552        self.serialize_str(buf.format(v))
553    }
554
555    fn serialize_char(self, v: char) -> Result<(), CsvError> {
556        let mut buf = [0u8; 4];
557        let s = v.encode_utf8(&mut buf);
558        self.serialize_str(s)
559    }
560
561    fn serialize_str(self, v: &str) -> Result<(), CsvError> {
562        self.write_field_bytes(v.as_bytes());
563        Ok(())
564    }
565
566    fn serialize_bytes(self, v: &[u8]) -> Result<(), CsvError> {
567        self.write_field_bytes(v);
568        Ok(())
569    }
570
571    fn serialize_none(self) -> Result<(), CsvError> {
572        self.write_field_bytes(b"");
573        Ok(())
574    }
575
576    fn serialize_some<T: ?Sized + serde::Serialize>(self, value: &T) -> Result<(), CsvError> {
577        value.serialize(self)
578    }
579
580    fn serialize_unit(self) -> Result<(), CsvError> {
581        self.write_field_bytes(b"");
582        Ok(())
583    }
584
585    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), CsvError> {
586        self.write_field_bytes(b"");
587        Ok(())
588    }
589
590    fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(
591        self,
592        _name: &'static str,
593        value: &T,
594    ) -> Result<(), CsvError> {
595        value.serialize(self)
596    }
597
598    fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
599        self,
600        _name: &'static str,
601        _idx: u32,
602        _variant: &'static str,
603        _value: &T,
604    ) -> Result<(), CsvError> {
605        Err(CsvError::custom("enum variants not supported"))
606    }
607
608    fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result<(), CsvError> {
609        Err(CsvError::custom("enum variants not supported"))
610    }
611
612    fn serialize_tuple_variant(
613        self,
614        _name: &'static str,
615        _idx: u32,
616        _variant: &'static str,
617        _len: usize,
618    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
619        Err(CsvError::custom("enum variants not supported"))
620    }
621
622    fn serialize_struct_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_map(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
633        Err(CsvError::custom("maps not supported"))
634    }
635}
636
637impl StructSer<'_, '_> {
638    fn write_field_bytes(&mut self, bytes: &[u8]) {
639        if let Some(slot) = self.values.first_mut() {
640            *slot = Some(bytes.to_vec());
641        }
642        *self.field_count = 1;
643    }
644}
645
646/// Collects struct fields by name and stores them at header-matching positions.
647struct StructCollector<'a, 'b> {
648    headers: &'a [String],
649    values: &'b mut Vec<Option<Vec<u8>>>,
650    field_count: &'b mut usize,
651    capture_buf: &'b mut Vec<u8>,
652}
653
654impl ser::SerializeStruct for StructCollector<'_, '_> {
655    type Ok = ();
656    type Error = CsvError;
657
658    fn serialize_field<T: ?Sized + serde::Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), CsvError> {
659        let pos = self
660            .headers
661            .iter()
662            .position(|h| h == key)
663            .ok_or_else(|| CsvError::custom(alloc::format!("unknown field '{key}'")))?;
664
665        self.capture_buf.clear();
666        {
667            let mut capture = FieldCapture {
668                buf: self.capture_buf,
669            };
670            value.serialize(&mut capture)?;
671        }
672        self.values[pos] = Some(core::mem::take(self.capture_buf));
673        *self.field_count += 1;
674        Ok(())
675    }
676
677    fn end(self) -> Result<(), CsvError> {
678        Ok(())
679    }
680}
681
682/// Writes seq/tuple elements positionally into the values array.
683struct SeqWriter<'b> {
684    values: &'b mut Vec<Option<Vec<u8>>>,
685    field_count: &'b mut usize,
686    idx: usize,
687    capture_buf: &'b mut Vec<u8>,
688}
689
690impl ser::SerializeSeq for SeqWriter<'_> {
691    type Ok = ();
692    type Error = CsvError;
693
694    fn serialize_element<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
695        if self.idx >= self.values.len() {
696            return Err(CsvError::custom("sequence longer than header count"));
697        }
698        self.capture_buf.clear();
699        {
700            let mut capture = FieldCapture {
701                buf: self.capture_buf,
702            };
703            value.serialize(&mut capture)?;
704        }
705        self.values[self.idx] = Some(core::mem::take(self.capture_buf));
706        self.idx += 1;
707        *self.field_count += 1;
708        Ok(())
709    }
710
711    fn end(self) -> Result<(), CsvError> {
712        if self.idx != self.values.len() {
713            return Err(CsvError::custom("sequence length does not match header count"));
714        }
715        Ok(())
716    }
717}
718
719impl ser::SerializeTuple for SeqWriter<'_> {
720    type Ok = ();
721    type Error = CsvError;
722
723    fn serialize_element<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
724        ser::SerializeSeq::serialize_element(self, value)
725    }
726
727    fn end(self) -> Result<(), CsvError> {
728        ser::SerializeSeq::end(self)
729    }
730}
731
732impl ser::SerializeTupleStruct for SeqWriter<'_> {
733    type Ok = ();
734    type Error = CsvError;
735
736    fn serialize_field<T: ?Sized + serde::Serialize>(&mut self, value: &T) -> Result<(), CsvError> {
737        ser::SerializeSeq::serialize_element(self, value)
738    }
739
740    fn end(self) -> Result<(), CsvError> {
741        ser::SerializeSeq::end(self)
742    }
743}
744
745/// Captures a single serialized field value into a `Vec<u8>`.
746struct FieldCapture<'a> {
747    buf: &'a mut Vec<u8>,
748}
749
750impl<'a> serde::Serializer for &'a mut FieldCapture<'a> {
751    type Ok = ();
752    type Error = CsvError;
753
754    type SerializeSeq = serde::ser::Impossible<(), CsvError>;
755    type SerializeTuple = serde::ser::Impossible<(), CsvError>;
756    type SerializeTupleStruct = serde::ser::Impossible<(), CsvError>;
757    type SerializeTupleVariant = serde::ser::Impossible<(), CsvError>;
758    type SerializeMap = serde::ser::Impossible<(), CsvError>;
759    type SerializeStruct = serde::ser::Impossible<(), CsvError>;
760    type SerializeStructVariant = serde::ser::Impossible<(), CsvError>;
761
762    fn serialize_bool(self, v: bool) -> Result<(), CsvError> {
763        let s = if v { "true" } else { "false" };
764        self.buf.extend_from_slice(s.as_bytes());
765        Ok(())
766    }
767
768    fn serialize_i8(self, v: i8) -> Result<(), CsvError> {
769        self.serialize_str(&format_number::format_int(v))
770    }
771    fn serialize_i16(self, v: i16) -> Result<(), CsvError> {
772        self.serialize_str(&format_number::format_int(v))
773    }
774    fn serialize_i32(self, v: i32) -> Result<(), CsvError> {
775        self.serialize_str(&format_number::format_int(v))
776    }
777    fn serialize_i64(self, v: i64) -> Result<(), CsvError> {
778        self.serialize_str(&format_number::format_int(v))
779    }
780    fn serialize_i128(self, v: i128) -> Result<(), CsvError> {
781        self.serialize_str(&format_number::format_int(v))
782    }
783    fn serialize_u8(self, v: u8) -> Result<(), CsvError> {
784        self.serialize_str(&format_number::format_int(v))
785    }
786    fn serialize_u16(self, v: u16) -> Result<(), CsvError> {
787        self.serialize_str(&format_number::format_int(v))
788    }
789    fn serialize_u32(self, v: u32) -> Result<(), CsvError> {
790        self.serialize_str(&format_number::format_int(v))
791    }
792    fn serialize_u64(self, v: u64) -> Result<(), CsvError> {
793        self.serialize_str(&format_number::format_int(v))
794    }
795    fn serialize_u128(self, v: u128) -> Result<(), CsvError> {
796        self.serialize_str(&format_number::format_int(v))
797    }
798    fn serialize_f32(self, v: f32) -> Result<(), CsvError> {
799        let mut buf = ryu::Buffer::new();
800        self.serialize_str(buf.format(v))
801    }
802    fn serialize_f64(self, v: f64) -> Result<(), CsvError> {
803        let mut buf = ryu::Buffer::new();
804        self.serialize_str(buf.format(v))
805    }
806
807    fn serialize_char(self, v: char) -> Result<(), CsvError> {
808        let mut buf = [0u8; 4];
809        let s = v.encode_utf8(&mut buf);
810        self.buf.extend_from_slice(s.as_bytes());
811        Ok(())
812    }
813
814    fn serialize_str(self, v: &str) -> Result<(), CsvError> {
815        self.buf.extend_from_slice(v.as_bytes());
816        Ok(())
817    }
818
819    fn serialize_bytes(self, v: &[u8]) -> Result<(), CsvError> {
820        self.buf.extend_from_slice(v);
821        Ok(())
822    }
823
824    fn serialize_none(self) -> Result<(), CsvError> {
825        Ok(())
826    }
827
828    fn serialize_some<T: ?Sized + serde::Serialize>(self, value: &T) -> Result<(), CsvError> {
829        value.serialize(self)
830    }
831
832    fn serialize_unit(self) -> Result<(), CsvError> {
833        Ok(())
834    }
835
836    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), CsvError> {
837        Ok(())
838    }
839
840    fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(
841        self,
842        _name: &'static str,
843        value: &T,
844    ) -> Result<(), CsvError> {
845        value.serialize(self)
846    }
847
848    fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
849        self,
850        _name: &'static str,
851        _idx: u32,
852        _variant: &'static str,
853        _value: &T,
854    ) -> Result<(), CsvError> {
855        Err(CsvError::custom("enum variants not supported in field capture"))
856    }
857
858    fn serialize_unit_variant(self, _name: &'static str, _idx: u32, _variant: &'static str) -> Result<(), CsvError> {
859        Err(CsvError::custom("enum variants not supported in field capture"))
860    }
861
862    fn serialize_tuple_variant(
863        self,
864        _name: &'static str,
865        _idx: u32,
866        _variant: &'static str,
867        _len: usize,
868    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
869        Err(CsvError::custom("enum variants not supported in field capture"))
870    }
871
872    fn serialize_struct_variant(
873        self,
874        _name: &'static str,
875        _idx: u32,
876        _variant: &'static str,
877        _len: usize,
878    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
879        Err(CsvError::custom("enum variants not supported in field capture"))
880    }
881
882    fn serialize_seq(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
883        Err(CsvError::custom("sequence inside a single field not supported"))
884    }
885
886    fn serialize_tuple(self, _len: usize) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
887        Err(CsvError::custom("tuple inside a single field not supported"))
888    }
889
890    fn serialize_tuple_struct(
891        self,
892        _name: &'static str,
893        _len: usize,
894    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
895        Err(CsvError::custom("tuple struct inside a single field not supported"))
896    }
897
898    fn serialize_map(self, _len: Option<usize>) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
899        Err(CsvError::custom("map inside a single field not supported"))
900    }
901
902    fn serialize_struct(
903        self,
904        _name: &'static str,
905        _len: usize,
906    ) -> Result<serde::ser::Impossible<(), CsvError>, CsvError> {
907        Err(CsvError::custom("struct inside a single field not supported"))
908    }
909}