use crate::csv::deser::utils::diagnostic::{
format_csv_error as generic_format_csv_error, CsvDiagnosticFormatter, CsvDiagnosticLayout,
CsvDiagnosticLocalization, CsvFieldResolver, CsvPositionFormatter,
};
use crate::csv::stanis::field_name;
use crate::deser::TipoRecord;
pub struct EngCsvDiagnostic;
impl CsvDiagnosticLocalization for EngCsvDiagnostic {
fn io_error(&self) -> &'static str {
"I/O error"
}
fn utf8_error(&self) -> &'static str {
"UTF-8 error"
}
fn unexpected_eof(&self) -> &'static str {
"Unexpected EOF"
}
fn parse_generic_error(&self) -> &'static str {
"Generic deserialization error"
}
fn parse_utf8_error(&self) -> &'static str {
"UTF-8 deserialzsation error"
}
fn parse_bool_error(&self) -> &'static str {
"Bool deserialization error"
}
fn parse_float_error(&self) -> &'static str {
"Float deserialization error"
}
fn parse_int_error(&self) -> &'static str {
"Integer deserialization error"
}
fn unsupported(&self) -> &'static str {
"Unsupported format"
}
fn unknown(&self) -> &'static str {
"Unknown error"
}
}
pub struct EngCsvPosition;
impl CsvPositionFormatter for EngCsvPosition {
fn format(&self, pos: Option<&csv::Position>) -> String {
match pos {
Some(p) => format!(
"line {}, record {}, byte {}",
p.line(),
p.record(),
p.byte()
),
None => "unknown".to_string(),
}
}
}
pub struct EngCsvFieldResolver;
impl CsvFieldResolver for EngCsvFieldResolver {
fn resolve(&self, record: TipoRecord, idx: usize) -> String {
field_name(record, idx)
}
}
pub struct EngCsvDiagnosticLayout;
impl CsvDiagnosticLayout for EngCsvDiagnosticLayout {
fn deserialize(&self, base: &str, pos: &str, field: &str, detail: &str) -> String {
format!("{base} ({pos}, field {field}) {}", detail)
}
fn unequal_lengths(&self, pos: &str, expected: u64, found: u64) -> String {
format!(
"Number of fields error at ({pos}) expected {} found {}",
expected, found
)
}
fn io(&self, base: &str, pos: &str, detail: &str) -> String {
format!("{} ({pos}): {}", base, detail)
}
fn utf8(&self, base: &str, pos: &str, detail: &str) -> String {
format!("{} ({pos}): {}", base, detail)
}
fn unknown(&self, base: &str, pos: &str, detail: &str) -> String {
format!("{} ({pos}): {}", base, detail)
}
}
pub(crate) type EngDiagnosticFormatter = CsvDiagnosticFormatter<
EngCsvDiagnostic,
EngCsvPosition,
EngCsvFieldResolver,
EngCsvDiagnosticLayout,
>;
impl EngDiagnosticFormatter {
pub(crate) fn new() -> Self {
Self {
loc: EngCsvDiagnostic,
pos: EngCsvPosition,
field: EngCsvFieldResolver,
layout: EngCsvDiagnosticLayout,
}
}
}
pub fn format_csv_error(error: &csv::Error, record: TipoRecord) -> String {
generic_format_csv_error(EngDiagnosticFormatter::new(), error, record)
}
pub fn format_csv_errors(errors: &[csv::Error], record: TipoRecord) -> Vec<String> {
errors.iter().map(|e| format_csv_error(e, record)).collect()
}