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 {}