h2s_core/
display.rs

1//! All implementations of Display trait.
2//! Defining human-readable string is a different context from HTML-parsing process, so separate it and aggregate implementations here
3
4use std::fmt::{Display, Formatter};
5
6use crate::element_selector::{Root, Select};
7use crate::extraction_method::{
8    AttributeNotFound, ExtractAttribute, ExtractInnerText, ExtractNthText, ExtractionMethod, NoOp,
9    NotFound,
10};
11use crate::functor::ExactlyOne;
12use crate::macro_utils::{ExtractionError, ParseError, ProcessError, TransformError};
13use crate::transformable::{VecToArrayError, VecToOptionError, VecToSingleError};
14use crate::traversable_with_context::{Context, ListIndex, NoContext};
15use crate::Never;
16use crate::{Error, FieldError};
17
18impl Display for VecToSingleError {
19    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20        match &self {
21            VecToSingleError::TooManyElements { found } => {
22                write!(
23                    f,
24                    "expected exactly one element, but {found} elements found"
25                )
26            }
27            VecToSingleError::NoElements => {
28                write!(f, "expected exactly one element, but no elements found")
29            }
30        }
31    }
32}
33
34impl Display for VecToOptionError {
35    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
36        match &self {
37            VecToOptionError::TooManyElements { found } => {
38                write!(f, "expected 0 or 1 element, but found {found} elements")
39            }
40        }
41    }
42}
43
44impl Display for VecToArrayError {
45    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46        match &self {
47            VecToArrayError::ElementNumberUnmatched { expected, found } => {
48                write!(
49                    f,
50                    "expected {expected} elements, but found {found} elements"
51                )
52            }
53        }
54    }
55}
56
57impl Display for Never {
58    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59        // never reached here
60        write!(f, "")
61    }
62}
63
64impl Display for AttributeNotFound {
65    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66        write!(
67            f,
68            "an attribute `{}` not found in the target element",
69            self.name
70        )
71    }
72}
73
74impl Display for FieldError {
75    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
76        write!(f, "{}: {}", self.field_name, self.error)
77    }
78}
79
80impl<A, B, C> Display for ProcessError<A, B, C>
81where
82    A: Error,
83    B: Error,
84    C: Error,
85{
86    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87        match self {
88            Self::TransformError(e) => write!(f, "{}", e),
89            Self::ExtractionError(e) => write!(f, "{}", e),
90            Self::ParseError(e) => write!(f, "{}", e),
91        }
92    }
93}
94
95impl<E> Display for TransformError<Select, E>
96where
97    E: Error,
98{
99    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
100        write!(
101            f,
102            "mismatched number of selected elements by \"{}\": {}",
103            self.selector, self.error
104        )
105    }
106}
107
108impl<E> Display for TransformError<Root, E>
109where
110    E: Error,
111{
112    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
113        // In fact, this error may never occur because transforming from root element always success
114        // So the user may never see the error message
115        write!(f, "mismatched structure: {}", self.error)
116    }
117}
118
119impl<C, M> Display for ExtractionError<C, M>
120where
121    C: Context,
122    M: ExtractionMethod,
123{
124    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
125        write!(
126            f,
127            "{}: failed to extract value of {}: {}",
128            self.context, self.extraction_method, self.error
129        )
130    }
131}
132
133impl<C, E> Display for ParseError<C, E>
134where
135    C: Context,
136    E: Error,
137{
138    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
139        // Just displaying an inner error because error is originally caused at more inside of the inner struct
140        write!(f, "{}: {}", self.context, self.error)
141    }
142}
143
144impl Display for Select {
145    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
146        write!(f, "{}", self.selector)
147    }
148}
149
150impl Display for Root {
151    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
152        write!(f, "-")
153    }
154}
155
156impl Display for ExtractAttribute {
157    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
158        write!(f, "attribute={}", self.name)
159    }
160}
161impl Display for ExtractInnerText {
162    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
163        write!(f, "inner text")
164    }
165}
166impl Display for NoOp {
167    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
168        write!(f, "no-op")
169    }
170}
171
172impl<T> Display for ExactlyOne<T>
173where
174    T: Display,
175{
176    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
177        write!(f, "ExactlyOne({})", self.0)
178    }
179}
180
181impl Display for ListIndex {
182    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183        write!(f, "[{}]", self.0)
184    }
185}
186
187impl Display for NoContext {
188    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
189        write!(f, "")
190    }
191}
192
193impl Display for ExtractNthText {
194    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
195        write!(f, "ExtractNthText({})", self.0)
196    }
197}
198
199impl Display for NotFound {
200    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
201        write!(f, "text node of the specified number is not found")
202    }
203}