1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq)]
5pub enum Value {
6 String(String),
8 U8(u8),
10 U16(u16),
12 U32(u32),
14 I16(i16),
16 I32(i32),
18 URational(u32, u32),
20 IRational(i32, i32),
22 F32(f32),
24 F64(f64),
26 Binary(Vec<u8>),
28 List(Vec<Value>),
30 Undefined(Vec<u8>),
32}
33
34impl Value {
35 pub fn to_display_string(&self) -> String {
37 match self {
38 Value::String(s) => s.clone(),
39 Value::U8(v) => v.to_string(),
40 Value::U16(v) => v.to_string(),
41 Value::U32(v) => v.to_string(),
42 Value::I16(v) => v.to_string(),
43 Value::I32(v) => v.to_string(),
44 Value::URational(n, d) => {
45 if *d == 0 {
46 if *n == 0 { "undef".to_string() } else { "inf".to_string() }
47 } else if *n % *d == 0 {
48 (*n / *d).to_string()
49 } else {
50 format!("{}/{}", n, d)
51 }
52 }
53 Value::IRational(n, d) => {
54 if *d == 0 {
55 if *n >= 0 { "inf".to_string() } else { "-inf".to_string() }
56 } else if *n % *d == 0 {
57 (*n / *d).to_string()
58 } else {
59 format!("{}/{}", n, d)
60 }
61 }
62 Value::F32(v) => format!("{}", v),
63 Value::F64(v) => format!("{}", v),
64 Value::Binary(data) => format!("(Binary data {} bytes)", data.len()),
65 Value::List(items) => {
66 items
67 .iter()
68 .map(|v| v.to_display_string())
69 .collect::<Vec<_>>()
70 .join(", ")
71 }
72 Value::Undefined(data) => format!("(Undefined {} bytes)", data.len()),
73 }
74 }
75
76 pub fn as_f64(&self) -> Option<f64> {
78 match self {
79 Value::U8(v) => Some(*v as f64),
80 Value::U16(v) => Some(*v as f64),
81 Value::U32(v) => Some(*v as f64),
82 Value::I16(v) => Some(*v as f64),
83 Value::I32(v) => Some(*v as f64),
84 Value::F32(v) => Some(*v as f64),
85 Value::F64(v) => Some(*v),
86 Value::URational(n, d) if *d != 0 => Some(*n as f64 / *d as f64),
87 Value::IRational(n, d) if *d != 0 => Some(*n as f64 / *d as f64),
88 _ => None,
89 }
90 }
91
92 pub fn as_str(&self) -> Option<&str> {
94 match self {
95 Value::String(s) => Some(s),
96 _ => None,
97 }
98 }
99
100 pub fn as_u64(&self) -> Option<u64> {
102 match self {
103 Value::U8(v) => Some(*v as u64),
104 Value::U16(v) => Some(*v as u64),
105 Value::U32(v) => Some(*v as u64),
106 _ => None,
107 }
108 }
109}
110
111impl fmt::Display for Value {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "{}", self.to_display_string())
114 }
115}