Skip to main content

rd_ast/rds/
error.rs

1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[non_exhaustive]
5pub enum LowerError {
6    RootMustBeList {
7        location: LowerLocation,
8    },
9    InvalidStringEncoding {
10        location: LowerLocation,
11        encoding: StringEncoding,
12    },
13    UnsupportedValue {
14        location: LowerLocation,
15    },
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct LowerLocation {
20    pub(super) path: RdPath,
21    pub(super) tag: Option<String>,
22    pub(super) attribute: Option<String>,
23}
24
25impl LowerLocation {
26    pub fn path(&self) -> &RdPath {
27        &self.path
28    }
29    pub fn tag(&self) -> Option<&str> {
30        self.tag.as_deref()
31    }
32    pub fn attribute(&self) -> Option<&str> {
33        self.attribute.as_deref()
34    }
35}
36
37impl fmt::Display for LowerLocation {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        if self.path.segments().is_empty() {
40            f.write_str("document root")?;
41        } else {
42            self.path.fmt(f)?;
43        }
44        if self.tag.is_some() || self.attribute.is_some() {
45            f.write_str(" (")?;
46            if let Some(tag) = &self.tag {
47                f.write_str(tag)?;
48            }
49            if let Some(attribute) = &self.attribute {
50                if self.tag.is_some() {
51                    f.write_str(", ")?;
52                }
53                write!(f, "@{attribute}")?;
54            }
55            f.write_str(")")?;
56        }
57        Ok(())
58    }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62#[non_exhaustive]
63pub enum StringEncoding {
64    Native,
65    Utf8,
66    Latin1,
67    Bytes,
68}
69
70impl fmt::Display for StringEncoding {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        f.write_str(match self {
73            Self::Native => "Native",
74            Self::Utf8 => "Utf8",
75            Self::Latin1 => "Latin1",
76            Self::Bytes => "Bytes",
77        })
78    }
79}
80
81impl LowerError {
82    pub fn location(&self) -> &LowerLocation {
83        match self {
84            Self::RootMustBeList { location }
85            | Self::InvalidStringEncoding { location, .. }
86            | Self::UnsupportedValue { location } => location,
87        }
88    }
89    pub fn encoding(&self) -> Option<StringEncoding> {
90        match self {
91            Self::InvalidStringEncoding { encoding, .. } => Some(*encoding),
92            _ => None,
93        }
94    }
95}
96
97impl fmt::Display for LowerError {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        match self {
100            Self::RootMustBeList { location } => {
101                write!(f, "root Rd object must be a list at {location}")
102            }
103            Self::InvalidStringEncoding { location, encoding } => {
104                write!(f, "invalid {encoding} string encoding at {location}")
105            }
106            Self::UnsupportedValue { location } => {
107                write!(f, "unsupported R value at {location}")
108            }
109        }
110    }
111}
112
113impl std::error::Error for LowerError {}