aws_multipart_upload/codec/
csv.rs1use bytes::{BufMut, BytesMut};
2use csv::{Terminator, Writer as CsvWriter, WriterBuilder};
3use serde::Serialize;
4use std::io::Write;
5use tokio_util::codec::Encoder;
6
7use crate::AwsError;
8
9#[derive(Debug, thiserror::Error)]
10pub enum CsvCodecError {
11 #[error("csv error in encoding bytes {0}")]
12 CsvWriter(#[from] csv::Error),
13 #[error("io error {0}")]
14 Io(#[from] std::io::Error),
15}
16
17impl From<CsvCodecError> for AwsError {
18 fn from(value: CsvCodecError) -> Self {
19 Self::Codec(value.to_string())
20 }
21}
22
23#[derive(Debug, Clone, Default)]
25pub struct CsvCodec {
26 pub has_headers: bool,
27 pub term: Terminator,
28}
29
30impl CsvCodec {
31 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn with_headers(mut self) -> Self {
36 self.has_headers = true;
37 self
38 }
39
40 pub fn set_terminator(mut self, term: Terminator) -> Self {
41 self.term = term;
42 self
43 }
44
45 pub fn from_writer<W: Write>(&self, wtr: W) -> CsvWriter<W> {
46 WriterBuilder::new()
47 .has_headers(self.has_headers)
48 .terminator(self.term)
49 .from_writer(wtr)
50 }
51}
52
53impl<Item> Encoder<Item> for CsvCodec
54where
55 Item: Serialize + std::fmt::Debug,
56{
57 type Error = CsvCodecError;
58
59 fn encode(&mut self, item: Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
60 let mut csv = self.from_writer(vec![]);
61 csv.serialize(item)?;
65 let inner = csv.into_inner().map_err(|e| e.into_error())?;
66 dst.reserve(inner.len());
67 dst.put_slice(&inner);
68 Ok(())
69 }
70}