Add DatatypeError

This commit is contained in:
mb 2024-06-24 17:39:25 +02:00
parent c94c53ac86
commit a7fe743850
No known key found for this signature in database

View file

@ -80,6 +80,46 @@ generate_element!(
] ]
); );
/// Enum representing errors that can occur while parsing a `Datatype`.
#[derive(Debug, Clone, PartialEq)]
pub enum DatatypeError {
/// Error indicating that a prefix is missing in the validation datatype.
MissingPrefix {
/// The invalid string that caused this error.
input: String,
},
/// Error indicating that the validation datatype is invalid.
InvalidType {
/// The invalid string that caused this error.
input: String,
},
/// Error indicating that the validation datatype is unknown.
UnknownType {
/// The invalid string that caused this error.
input: String,
},
}
impl std::error::Error for DatatypeError {}
impl Display for DatatypeError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
DatatypeError::MissingPrefix { input } => {
write!(f, "Missing prefix in validation datatype '{input}'.")
}
DatatypeError::InvalidType { input } => {
write!(f, "Invalid validation datatype '{input}'.")
}
DatatypeError::UnknownType { input } => {
write!(f, "Unknown validation datatype '{input}'.")
}
}
}
}
/// Data Forms Validation Datatypes /// Data Forms Validation Datatypes
/// ///
/// https://xmpp.org/registrar/xdv-datatypes.html /// https://xmpp.org/registrar/xdv-datatypes.html
@ -186,7 +226,11 @@ impl TryFrom<Element> for Validate {
check_no_unknown_attributes!(elem, "item", ["datatype"]); check_no_unknown_attributes!(elem, "item", ["datatype"]);
let mut validate = Validate { let mut validate = Validate {
datatype: elem.attr("datatype").map(Datatype::from_str).transpose()?, datatype: elem
.attr("datatype")
.map(Datatype::from_str)
.transpose()
.map_err(|err| FromElementError::Invalid(Error::TextParseError(err.into())))?,
method: None, method: None,
list_range: None, list_range: None,
}; };
@ -274,16 +318,15 @@ impl From<Method> for Element {
} }
impl FromStr for Datatype { impl FromStr for Datatype {
type Err = Error; type Err = DatatypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.splitn(2, ":"); let mut parts = s.splitn(2, ":");
let Some(prefix) = parts.next() else { let Some(prefix) = parts.next() else {
return Err(Error::Other( return Err(DatatypeError::MissingPrefix {
"Encountered invalid validation datatype which is missing a prefix.", input: s.to_string(),
) });
.into());
}; };
match prefix { match prefix {
@ -302,7 +345,9 @@ impl FromStr for Datatype {
} }
let Some(datatype) = parts.next() else { let Some(datatype) = parts.next() else {
return Err(Error::Other("Encountered invalid validation datatype.").into()); return Err(DatatypeError::InvalidType {
input: s.to_string(),
});
}; };
let parsed_datatype = match datatype { let parsed_datatype = match datatype {
@ -319,7 +364,11 @@ impl FromStr for Datatype {
"short" => Datatype::Short, "short" => Datatype::Short,
"string" => Datatype::String, "string" => Datatype::String,
"time" => Datatype::Time, "time" => Datatype::Time,
_ => return Err(Error::Other("Encountered invalid validation datatype.").into()), _ => {
return Err(DatatypeError::UnknownType {
input: s.to_string(),
})
}
}; };
Ok(parsed_datatype) Ok(parsed_datatype)
@ -360,10 +409,20 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_parse_datatype() -> Result<(), Error> { fn test_parse_datatype() -> Result<(), DatatypeError> {
assert_eq!(Datatype::AnyUri, "xs:anyURI".parse()?); assert_eq!(Datatype::AnyUri, "xs:anyURI".parse()?);
assert!("xs:anyuri".parse::<Datatype>().is_err()); assert_eq!(
assert!("xs:".parse::<Datatype>().is_err()); Err(DatatypeError::UnknownType {
input: "xs:anyuri".to_string()
}),
"xs:anyuri".parse::<Datatype>(),
);
assert_eq!(
"xs:".parse::<Datatype>(),
Err(DatatypeError::UnknownType {
input: "xs:".to_string()
})
);
assert_eq!( assert_eq!(
Datatype::AnyUri.into_attribute_value(), Datatype::AnyUri.into_attribute_value(),
Some("xs:anyURI".to_string()) Some("xs:anyURI".to_string())