fits_well/header/
value.rs1#[derive(Debug, Clone, PartialEq)]
7pub enum Value {
8 Logical(bool),
10 Integer(i64),
11 Real(f64),
12 Text(String),
15 ComplexInteger {
16 re: i64,
17 im: i64,
18 },
19 ComplexReal {
20 re: f64,
21 im: f64,
22 },
23 Undefined,
25}
26
27impl Value {
28 pub fn as_logical(&self) -> Option<bool> {
29 match self {
30 Value::Logical(b) => Some(*b),
31 _ => None,
32 }
33 }
34
35 pub fn as_integer(&self) -> Option<i64> {
36 match self {
37 Value::Integer(i) => Some(*i),
38 Value::Real(r) if r.fract() == 0.0 => Some(*r as i64),
42 _ => None,
43 }
44 }
45
46 pub fn as_real(&self) -> Option<f64> {
48 match self {
49 Value::Real(r) => Some(*r),
50 Value::Integer(i) => Some(*i as f64),
51 _ => None,
52 }
53 }
54
55 pub fn as_text(&self) -> Option<&str> {
56 match self {
57 Value::Text(s) => Some(s),
58 _ => None,
59 }
60 }
61}
62
63impl From<bool> for Value {
64 fn from(b: bool) -> Self {
65 Value::Logical(b)
66 }
67}
68
69impl From<i64> for Value {
70 fn from(i: i64) -> Self {
71 Value::Integer(i)
72 }
73}
74
75impl From<i32> for Value {
76 fn from(i: i32) -> Self {
77 Value::Integer(i as i64)
78 }
79}
80
81impl From<f64> for Value {
82 fn from(r: f64) -> Self {
83 Value::Real(r)
84 }
85}
86
87impl From<&str> for Value {
88 fn from(s: &str) -> Self {
89 Value::Text(s.to_string())
90 }
91}
92
93impl From<String> for Value {
94 fn from(s: String) -> Self {
95 Value::Text(s)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn accessors_only_match_their_own_variant() {
105 assert_eq!(Value::Logical(true).as_logical(), Some(true));
106 assert_eq!(Value::Logical(true).as_integer(), None);
107
108 assert_eq!(Value::Integer(42).as_integer(), Some(42));
109 assert_eq!(Value::Integer(42).as_logical(), None);
110
111 assert_eq!(Value::Text("x".into()).as_text(), Some("x"));
112 assert_eq!(Value::Text("x".into()).as_integer(), None);
113
114 assert_eq!(Value::Undefined.as_text(), None);
115 assert_eq!(Value::Undefined.as_real(), None);
116 }
117
118 #[test]
119 fn as_real_widens_integers_but_not_other_types() {
120 assert_eq!(Value::Real(1.5).as_real(), Some(1.5));
121 assert_eq!(Value::Integer(3).as_real(), Some(3.0));
122 assert_eq!(Value::Logical(true).as_real(), None);
123 }
124
125 #[test]
126 fn from_conversions_pick_the_right_variant() {
127 assert_eq!(Value::from(true), Value::Logical(true));
128 assert_eq!(Value::from(16_i32), Value::Integer(16));
129 assert_eq!(Value::from(16_i64), Value::Integer(16));
130 assert_eq!(Value::from(1.5_f64), Value::Real(1.5));
131 assert_eq!(Value::from("hi"), Value::Text("hi".into()));
132 assert_eq!(Value::from(String::from("hi")), Value::Text("hi".into()));
133 }
134}