add list of Valid Units to the Invalid Unit error message (#2701)

This commit is contained in:
don bright 2023-05-07 17:09:47 -05:00 committed by Olivier Goffart
parent cad884ff1f
commit a255aaf8d4
3 changed files with 20 additions and 6 deletions

View file

@ -59,6 +59,7 @@ image = { version = "0.24", optional = true }
resvg = { workspace = true, optional = true }
# font embedding
fontdue = { version = "0.7.1", optional = true }
strum_macros = "0.24.3"
[dev-dependencies]
i-slint-parser-test-macro = { path = "./parser-test-macro" }

View file

@ -320,7 +320,7 @@ pub fn operator_class(op: char) -> OperatorClass {
macro_rules! declare_units {
($( $(#[$m:meta])* $ident:ident = $string:literal -> $ty:ident $(* $factor:expr)? ,)*) => {
/// The units that can be used after numbers in the language
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, strum_macros::EnumIter)]
pub enum Unit {
$($(#[$m])* $ident,)*
}

View file

@ -2,6 +2,9 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
use crate::expression_tree::Expression;
use crate::expression_tree::Unit;
use itertools::Itertools;
use strum::IntoEnumIterator;
/// Returns `0xaarrggbb`
pub fn parse_color_literal(str: &str) -> Option<u32> {
@ -130,7 +133,13 @@ pub fn parse_number_literal(s: String) -> Result<Expression, String> {
end += 1;
}
let val = s[..end].parse().map_err(|_| "Cannot parse number literal".to_owned())?;
let unit = s[end..].parse().map_err(|_| "Invalid unit".to_owned())?;
let unit = s[end..].parse().map_err(|_| {
format!(
"Invalid unit '{}'. Valid units are: {}",
s.get(end..).unwrap_or(&s),
Unit::iter().filter(|x| x.to_string().len() > 0).join(",")
)
})?;
Ok(Expression::NumberLiteral(val, unit))
}
@ -154,10 +163,14 @@ fn test_parse_number_literal() {
assert_eq!(doit("10000000"), Ok((10000000., Unit::None)));
assert_eq!(doit("10000001phx"), Ok((10000001., Unit::Phx)));
let wrong_unit = Err("Invalid unit".to_owned());
let cannot_parse = Err("Cannot parse number literal".to_owned());
assert_eq!(doit("10000001 phx"), wrong_unit);
assert_eq!(doit("12.10.12phx"), cannot_parse);
assert_eq!(doit("12.12oo"), wrong_unit);
assert_eq!(doit("12.12€"), wrong_unit);
let valid_units = Unit::iter().filter(|x| x.to_string().len() > 0).join(",");
let wrong_unit_spaced = Err(format!("Invalid unit ' phx'. Valid units are: {}", valid_units));
assert_eq!(doit("10000001 phx"), wrong_unit_spaced);
let wrong_unit_oo = Err(format!("Invalid unit 'oo'. Valid units are: {}", valid_units));
assert_eq!(doit("12.12oo"), wrong_unit_oo);
let wrong_unit_euro = Err(format!("Invalid unit '€'. Valid units are: {}", valid_units));
assert_eq!(doit("12.12€"), wrong_unit_euro);
}