1use alloc::string::String;
4use core::fmt;
5
6#[derive(Debug, Clone)]
8pub struct CsvError {
9 kind: CsvErrorKind,
10 #[allow(dead_code)]
12 span: Option<facet_reflect::Span>,
13}
14
15impl CsvError {
16 pub const fn new(kind: CsvErrorKind) -> Self {
18 Self { kind, span: None }
19 }
20
21 pub const fn with_span(kind: CsvErrorKind, span: facet_reflect::Span) -> Self {
23 Self {
24 kind,
25 span: Some(span),
26 }
27 }
28
29 pub const fn kind(&self) -> &CsvErrorKind {
31 &self.kind
32 }
33}
34
35impl fmt::Display for CsvError {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match &self.kind {
38 CsvErrorKind::UnexpectedEof { expected } => {
39 write!(f, "unexpected end of input, expected {expected}")
40 }
41 CsvErrorKind::InvalidValue { message } => write!(f, "invalid value: {message}"),
42 CsvErrorKind::UnsupportedType { type_name } => {
43 write!(f, "unsupported type for CSV: {type_name}")
44 }
45 CsvErrorKind::TooFewFields { expected, got } => {
46 write!(f, "too few fields: expected {expected}, got {got}")
47 }
48 CsvErrorKind::TooManyFields { expected, got } => {
49 write!(f, "too many fields: expected {expected}, got {got}")
50 }
51 CsvErrorKind::InvalidUtf8 { message } => {
52 write!(f, "invalid UTF-8: {message}")
53 }
54 }
55 }
56}
57
58impl std::error::Error for CsvError {}
59
60#[derive(Debug, Clone)]
62pub enum CsvErrorKind {
63 UnexpectedEof {
65 expected: &'static str,
67 },
68 InvalidValue {
70 message: String,
72 },
73 UnsupportedType {
75 type_name: &'static str,
77 },
78 TooFewFields {
80 expected: usize,
82 got: usize,
84 },
85 TooManyFields {
87 expected: usize,
89 got: usize,
91 },
92 InvalidUtf8 {
94 message: String,
96 },
97}
98
99impl From<CsvErrorKind> for CsvError {
100 fn from(kind: CsvErrorKind) -> Self {
101 Self::new(kind)
102 }
103}