precis_core/
error.rs

1use crate::DerivedPropertyValue;
2use std::fmt;
3
4/// Represents any kind of error that may happen when
5/// preparing, enforcing or comparing internationalized
6/// strings
7#[derive(Debug, PartialEq, Eq)]
8pub enum Error {
9    /// Invalid label
10    Invalid,
11    /// Detected a disallowed Unicode code pint in the label.
12    /// [`CodepointInfo`] contains information about the code point.
13    BadCodepoint(CodepointInfo),
14    /// Error used to deal with any unexpected condition not directly
15    /// covered by any other category.
16    Unexpected(UnexpectedError),
17}
18
19impl fmt::Display for Error {
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        match self {
22            Error::Invalid => write!(f, "invalid label"),
23            Error::BadCodepoint(info) => write!(f, "bad codepoint: {}", info),
24            Error::Unexpected(unexpected) => write!(f, "unexpected: {}", unexpected),
25        }
26    }
27}
28
29impl std::error::Error for Error {}
30
31/// Error that contains information regarding the wrong Unicode code point
32#[derive(Debug, PartialEq, Eq)]
33pub struct CodepointInfo {
34    /// Unicode code point
35    pub cp: u32,
36    /// The position of the Unicode code point in the label
37    pub position: usize,
38    /// The derived property value
39    pub property: DerivedPropertyValue,
40}
41
42impl CodepointInfo {
43    /// Creates a new `CodepointInfo` `struct`
44    pub fn new(cp: u32, position: usize, property: DerivedPropertyValue) -> Self {
45        Self {
46            cp,
47            position,
48            property,
49        }
50    }
51}
52
53impl fmt::Display for CodepointInfo {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        write!(
56            f,
57            "code point {:#06x}, position: {}, property: {}",
58            self.cp, self.position, self.property
59        )
60    }
61}
62
63/// Internal errors that group unusual error conditions that mostly
64/// have to do with the processing of wrong labels, unexpected Unicode
65/// code points if tested against another version defined in PRECIS, etc.
66#[derive(Debug, PartialEq, Eq)]
67pub enum UnexpectedError {
68    /// Error caused when trying to apply a context rule over
69    /// an invalid code point.
70    ContextRuleNotApplicable(CodepointInfo),
71    /// The code point requires a context rule that is not implemented.
72    /// [`CodepointInfo`] contains information about the code point.
73    MissingContextRule(CodepointInfo),
74    /// Error caused when trying to apply a context rule that is not defined
75    /// by the PRECIS profile.
76    ProfileRuleNotApplicable,
77    /// Unexpected error condition such as an attempt to access to a character before
78    /// the start of a label or after the end of a label.
79    Undefined,
80}
81
82impl fmt::Display for UnexpectedError {
83    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84        match self {
85            UnexpectedError::ContextRuleNotApplicable(info) => {
86                write!(f, "context rule not applicable [{}]", info)
87            }
88            UnexpectedError::MissingContextRule(info) => {
89                write!(f, "missing context rule [{}]", info)
90            }
91            UnexpectedError::ProfileRuleNotApplicable => write!(f, "profile rule not appplicable"),
92            UnexpectedError::Undefined => write!(f, "undefined"),
93        }
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn fmt_error() {
103        format!("{}", Error::Invalid);
104        format!(
105            "{}",
106            Error::BadCodepoint(CodepointInfo {
107                cp: 0,
108                position: 0,
109                property: DerivedPropertyValue::PValid
110            })
111        );
112        format!("{}", Error::Unexpected(UnexpectedError::Undefined));
113    }
114
115    #[test]
116    fn fmt_unexpected_error() {
117        format!("{}", UnexpectedError::Undefined);
118        format!("{}", UnexpectedError::ProfileRuleNotApplicable);
119        format!(
120            "{}",
121            UnexpectedError::MissingContextRule(CodepointInfo {
122                cp: 0,
123                position: 0,
124                property: DerivedPropertyValue::PValid
125            })
126        );
127        format!(
128            "{}",
129            UnexpectedError::ContextRuleNotApplicable(CodepointInfo {
130                cp: 0,
131                position: 0,
132                property: DerivedPropertyValue::PValid
133            })
134        );
135    }
136}