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