aws_multipart_upload/encoder/
csv_encoder.rs1use csv::{Error as CsvError, Writer, WriterBuilder};
2use serde::Serialize;
3
4use super::{EncodeError, EncodeErrorKind, PartEncoder};
5use crate::request::{PartBody, PartNumber};
6
7#[derive(Debug, Clone, Copy)]
9pub struct CsvEncoder {
10 has_header: bool,
11 double_quotes: bool,
12}
13
14impl CsvEncoder {
15 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn skip_header(self) -> Self {
24 Self { has_header: false, double_quotes: self.double_quotes }
25 }
26
27 pub fn escape_quotes(self) -> Self {
33 Self { double_quotes: false, has_header: self.has_header }
34 }
35
36 fn csv_writer(
37 self,
38 wr: &mut PartBody,
39 is_first: bool,
40 ) -> Writer<&mut PartBody> {
41 let mut builder = WriterBuilder::new();
42 if is_first && wr.is_empty() {
43 builder.has_headers(self.has_header)
44 } else {
45 builder.has_headers(false)
47 }
48 .double_quote(self.double_quotes)
49 .from_writer(wr)
50 }
51}
52
53impl Default for CsvEncoder {
54 fn default() -> Self {
55 Self { has_header: true, double_quotes: true }
56 }
57}
58
59impl<Item: Serialize> PartEncoder<Item> for CsvEncoder {
60 type Error = CsvError;
61
62 fn encode(
63 &mut self,
64 part: &mut PartBody,
65 part_number: PartNumber,
66 item: Item,
67 ) -> Result<(), Self::Error> {
68 let mut writer = self.csv_writer(part, part_number.is_first());
69 writer.serialize(item)?;
70 writer.flush()?;
71 Ok(())
72 }
73}
74
75impl EncodeError for CsvError {
76 fn message(&self) -> String {
77 self.to_string()
78 }
79
80 fn kind(&self) -> EncodeErrorKind {
81 match self.kind() {
82 csv::ErrorKind::Io(_) => EncodeErrorKind::Io,
83 csv::ErrorKind::UnequalLengths { .. }
84 | csv::ErrorKind::Utf8 { .. }
85 | csv::ErrorKind::Deserialize { .. }
86 | csv::ErrorKind::Serialize(_) => EncodeErrorKind::Data,
87 csv::ErrorKind::Seek => EncodeErrorKind::Eof,
88 _ => EncodeErrorKind::Unknown,
89 }
90 }
91}