use std::convert::Infallible;
use std::fmt::{self, Display, Formatter};
use crate::client::part::{PartBody, PartNumber};
#[cfg(feature = "csv")]
#[cfg_attr(docsrs, doc(cfg(feature = "csv")))]
mod csv_encoder;
#[cfg(feature = "csv")]
#[cfg_attr(docsrs, doc(cfg(feature = "csv")))]
pub use csv_encoder::CsvEncoder;
#[cfg(feature = "tokio-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-util")))]
mod framed_encoder;
#[cfg(feature = "tokio-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-util")))]
pub use framed_encoder::FramedEncoder;
mod json_encoder;
pub use json_encoder::JsonLinesEncoder;
mod lines_encoder;
pub use lines_encoder::LinesEncoder;
pub trait PartEncoder<Item> {
type Error: EncodeError;
fn encode(
&mut self,
part: &mut PartBody,
part_number: PartNumber,
item: Item,
) -> Result<(), Self::Error>;
}
pub trait EncodeError: std::error::Error {
fn message(&self) -> String;
fn kind(&self) -> EncodeErrorKind;
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum EncodeErrorKind {
Io,
Data,
Eof,
#[default]
Unknown,
}
impl Display for EncodeErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let x = match self {
Self::Io => "io",
Self::Data => "data",
Self::Eof => "eof",
Self::Unknown => "unknown",
};
write!(f, "{x}")
}
}
impl EncodeError for std::io::Error {
fn message(&self) -> String {
self.to_string()
}
fn kind(&self) -> EncodeErrorKind {
EncodeErrorKind::Io
}
}
impl EncodeError for Infallible {
fn message(&self) -> String {
"unbelievable".into()
}
fn kind(&self) -> EncodeErrorKind {
EncodeErrorKind::Unknown
}
}
impl EncodeError for serde_json::Error {
fn message(&self) -> String {
self.to_string()
}
fn kind(&self) -> EncodeErrorKind {
match self.classify() {
serde_json::error::Category::Data
| serde_json::error::Category::Syntax => EncodeErrorKind::Data,
serde_json::error::Category::Eof => EncodeErrorKind::Eof,
serde_json::error::Category::Io => EncodeErrorKind::Io,
}
}
}