devalang_wasm/language/syntax/parser/driver/
duration.rs

1use crate::language::syntax::ast::DurationValue;
2use anyhow::{Result, anyhow};
3
4pub fn parse_duration_token(token: &str) -> Result<DurationValue> {
5    let token = token.trim();
6    if token.eq_ignore_ascii_case("auto") {
7        return Ok(DurationValue::Auto);
8    }
9
10    if let Some(value) = token.strip_suffix("ms") {
11        let ms: f32 = value
12            .parse()
13            .map_err(|_| anyhow!("invalid milliseconds duration: '{}'", token))?;
14        return Ok(DurationValue::Milliseconds(ms));
15    }
16
17    if let Some(fraction) = parse_fraction(token) {
18        return Ok(DurationValue::Beats(fraction));
19    }
20
21    if let Ok(number) = token.parse::<f32>() {
22        return Ok(DurationValue::Milliseconds(number));
23    }
24
25    Ok(DurationValue::Identifier(token.to_string()))
26}
27
28fn parse_fraction(token: &str) -> Option<f32> {
29    let mut split = token.split('/');
30    let numerator: f32 = split.next()?.trim().parse().ok()?;
31    let denominator: f32 = split.next()?.trim().parse().ok()?;
32    if denominator.abs() < f32::EPSILON {
33        return None;
34    }
35    Some(numerator / denominator)
36}