ID parsing: reject IDs with invalid prefix

This commit is contained in:
Smitty 2021-08-28 10:58:14 -04:00
parent 04fd6bedd3
commit d3e80e3a37

View file

@ -6,7 +6,7 @@ use std::{fmt, num::ParseIntError, str::FromStr};
pub mod consts; pub mod consts;
/// An error parsing an ID. /// An error parsing an ID.
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum IdParseError { pub enum IdParseError {
/// The number couldn't be parsed. /// The number couldn't be parsed.
UnparseableNumber(ParseIntError), UnparseableNumber(ParseIntError),
@ -15,7 +15,7 @@ pub enum IdParseError {
} }
macro_rules! id_def { macro_rules! id_def {
($name:ident, $full_name:expr, $letter:expr) => { ($name:ident, $full_name:expr, $letter:expr, $khar:expr) => {
#[derive( #[derive(
Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
)] )]
@ -42,7 +42,7 @@ macro_rules! id_def {
/// Parse the identifier from a string. /// Parse the identifier from a string.
fn from_str(x: &str) -> Result<Self, Self::Err> { fn from_str(x: &str) -> Result<Self, Self::Err> {
if x.is_empty() { if x.chars().next() != Some($khar) {
return Err(IdParseError::InvalidPrefix); return Err(IdParseError::InvalidPrefix);
} }
let num_str = &x[1..]; let num_str = &x[1..];
@ -61,9 +61,9 @@ macro_rules! id_def {
}; };
} }
id_def!(Qid, "entity ID", "Q"); id_def!(Qid, "entity ID", "Q", 'Q');
id_def!(Pid, "property ID", "P"); id_def!(Pid, "property ID", "P", 'P');
id_def!(Lid, "lexeme ID", "L"); id_def!(Lid, "lexeme ID", "L", 'L');
/// A lexeme ID and associated form ID /// A lexeme ID and associated form ID
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
@ -130,6 +130,8 @@ pub mod test {
assert_eq!(Qid::from_str("Q42").unwrap(), Qid(42)); assert_eq!(Qid::from_str("Q42").unwrap(), Qid(42));
assert_eq!(Lid::from_str("L944114").unwrap(), Lid(944114)); assert_eq!(Lid::from_str("L944114").unwrap(), Lid(944114));
assert_eq!(Pid::from_str("P1341").unwrap(), Pid(1341)); assert_eq!(Pid::from_str("P1341").unwrap(), Pid(1341));
assert_eq!(Pid::from_str("Q1341"), Err(IdParseError::InvalidPrefix));
assert_eq!(Pid::from_str("1341"), Err(IdParseError::InvalidPrefix));
} }
#[test] #[test]