Skip to main content

can_dbc/ast/
numeric_value.rs

1use std::str::FromStr;
2
3use crate::DbcError;
4
5#[derive(Clone, Copy, Debug, PartialEq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub enum NumericValue {
8    Uint(u64),
9    Int(i64),
10    Double(f64),
11}
12
13impl FromStr for NumericValue {
14    type Err = DbcError;
15
16    fn from_str(value: &str) -> Result<Self, Self::Err> {
17        if let Ok(v) = value.parse::<u64>() {
18            Ok(NumericValue::Uint(v))
19        } else if let Ok(v) = value.parse::<i64>() {
20            Ok(NumericValue::Int(v))
21        } else if let Ok(v) = value.parse::<f64>() {
22            Ok(NumericValue::Double(v))
23        } else {
24            Err(DbcError::InvalidNumericValue(value.to_string()))
25        }
26    }
27}
28
29impl std::fmt::Display for NumericValue {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        match self {
32            NumericValue::Uint(v) => write!(f, "{v}"),
33            NumericValue::Int(v) => write!(f, "{v}"),
34            NumericValue::Double(v) => write!(f, "{v}"),
35        }
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn unsigned_max() {
45        let value = u64::MAX.to_string();
46        assert_eq!(
47            format!("{}", NumericValue::from_str(&value).unwrap()),
48            value
49        );
50    }
51
52    #[test]
53    fn signed_min() {
54        let value = i64::MIN.to_string();
55        assert_eq!(
56            format!("{}", NumericValue::from_str(&value).unwrap()),
57            value
58        );
59    }
60
61    #[test]
62    fn double() {
63        let value = "3.141592653589793";
64        assert_eq!(format!("{}", NumericValue::from_str(value).unwrap()), value);
65    }
66}