in components/support/firefox-versioning/src/version.rs [235:301]
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
if !value.is_ascii() {
return Err(VersionParsingError::ParseError(format!(
"version string {} contains non-ascii characters",
value
)));
}
if value.is_empty() {
return Ok(Default::default());
}
let mut res: VersionPart = Default::default();
// if the string value is the special "*",
// then we set the num_a to be the highest possible value
// handle that case before we start
if value == "*" {
res.num_a = i32::MAX;
return Ok(res);
}
// Step 1: Parse the num_a, it's guaranteed to be
// a base-10 number, if it exists
let mut curr_idx = 0;
while curr_idx < value.len() && char_at(value, curr_idx)?.is_numeric() {
parse_version_num(
char_at(value, curr_idx)?.to_digit(10).unwrap() as i32,
&mut res.num_a,
)?;
curr_idx += 1;
}
if curr_idx >= value.len() {
return Ok(res);
}
// Step 2: Parse the str_b. If str_b starts with a "+"
// then we increment num_a, and set str_b to be "pre"
let first_char = char_at(value, curr_idx)?;
if first_char == '+' {
res.num_a += 1;
res.str_b = "pre".into();
return Ok(res);
}
// otherwise, we parse until we either finish the string
// or we find a numeric number, indicating the start of num_c
while curr_idx < value.len() && !is_num_c(char_at(value, curr_idx)?) {
res.str_b.push(char_at(value, curr_idx)?);
curr_idx += 1;
}
if curr_idx >= value.len() {
return Ok(res);
}
// Step 3: Parse the num_c, similar to how we parsed num_a
while curr_idx < value.len() && char_at(value, curr_idx)?.is_numeric() {
parse_version_num(
char_at(value, curr_idx)?.to_digit(10).unwrap() as i32,
&mut res.num_c,
)?;
curr_idx += 1;
}
if curr_idx >= value.len() {
return Ok(res);
}
// Step 4: Assign all the remaining to extra_d
res.extra_d = value[curr_idx..].into();
Ok(res)
}