#[derive(Eq, PartialEq, PartialOrd, Ord, Clone, Hash, Debug)]
pub struct Id(String);
impl TryFrom<&str> for Id {
type Error = Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let mut value_i = value.chars();
if match value_i.next() {
Some(some) => match some {
'_' | 'A'..='Z' | 'a'..='z' => true,
'0'..='9' | _ => false,
},
None => return Err(Error::EmptyId),
} {
value_i.next();
while let Some(c) = value_i.next() {
match c {
'_' | '0'..='9' | 'A'..='Z' | 'a'..='z' => continue,
_ => return Err(Error::BadId(String::from(value))),
}
}
}
Ok(Id(String::from(value)))
}
}
And this code looks horrible to me.
It does work correctly, but I feel like there is a better way to achieve what the function does. I would like to also ask about naming. Should I rename the structure type Id to Ident or Identifier, or is it fine?
If what the function does is not clear, it reads the given string value and returns an error if it contains a character other than '_' | '0'..='9' | 'A'..='Z' | 'a'..='z', and it also checks whether the string starts with a number.
How is the performance of your solution compared to the original? I would be really surprised when there is not an order of magnitude difference?
For the original, I think there are functions like is_ascii_alphabetic() and is_ascii_alphanumeric() which would make it simpler. Or perhaps convert the char to upper case first, so the test 'A'..='Z' is sufficient. But I guess due to Unicode that is not fast -- for plain ASCII it would be fast of course.
Actually I would try to do all the character comparisons with plain ASCII. I would assume that we could convert the original Unicode to Ascii, and then make a faster evaluation.
Gnuplot not found, using plotters backend
original_id time: [28.337 ns 28.451 ns 28.572 ns]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
idiomatic_id time: [23.265 ns 23.309 ns 23.361 ns]
Found 8 outliers among 100 measurements (8.00%)
6 (6.00%) high mild
2 (2.00%) high severe
ascii_id time: [19.232 ns 19.410 ns 19.602 ns]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high severe
OK, I tried. Personally for me, the output was fine, and now as code, I have a medium size view with horizontal and vertical scroll bars. That is, long lines, and bottom of code, needs scrolling.