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)]
62#[non_exhaustive]
63pub enum CsvErrorKind {
64 UnexpectedEof {
66 expected: &'static str,
68 },
69 InvalidValue {
71 message: String,
73 },
74 UnsupportedType {
76 type_name: &'static str,
78 },
79 TooFewFields {
81 expected: usize,
83 got: usize,
85 },
86 TooManyFields {
88 expected: usize,
90 got: usize,
92 },
93 InvalidUtf8 {
95 message: String,
97 },
98}
99
100impl From<CsvErrorKind> for CsvError {
101 fn from(kind: CsvErrorKind) -> Self {
102 Self::new(kind)
103 }
104}