can_dbc/ast/
numeric_value.rs1use 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}