num_parser/value/
mod.rs

1mod display;
2pub mod valuetype;
3
4use self::valuetype::ValueType;
5use super::out::*;
6use crate::{settings::Rounding, token::tokentype::TokenType};
7use num::complex::Complex64;
8
9pub type IntValue = i64;
10pub type FloatValue = f64;
11pub type ComplexValue = Complex64;
12pub type VectorValue = Vec<Value>;
13pub type BoolValue = bool;
14
15/// Represent every possible output value.
16#[derive(Debug, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Value {
19    Int(IntValue),
20    Float(FloatValue),
21    Complex(ComplexValue),
22    Vector(VectorValue),
23    Bool(BoolValue),
24}
25
26impl Value {
27    pub fn get_type(&self) -> ValueType {
28        match self {
29            Value::Float(_) => ValueType::FloatType,
30            Value::Int(_) => ValueType::IntType,
31            Value::Complex(_) => ValueType::ComplexType,
32            Value::Vector(_) => ValueType::VectorType,
33            Value::Bool(_) => ValueType::BoolType,
34        }
35    }
36
37    pub fn is_int(&self) -> bool {
38        matches!(self, Value::Int(_))
39    }
40
41    pub fn is_float(&self) -> bool {
42        matches!(self, Value::Float(_))
43    }
44
45    pub fn is_complex(&self) -> bool {
46        matches!(self, Value::Complex(_))
47    }
48
49    pub fn is_vector(&self) -> bool {
50        matches!(self, Value::Vector(_))
51    }
52
53    pub fn is_bool(&self) -> bool {
54        matches!(self, Value::Bool(_))
55    }
56
57    pub fn as_int(&self) -> EvalResult<IntValue> {
58        match self {
59            Value::Int(n) => Ok(*n),
60            Value::Float(n) => {
61                if n.fract() == 0.0 {
62                    Ok(*n as IntValue)
63                } else {
64                    Err(ErrorType::FailedCast {
65                        value: self.clone(),
66                        from: ValueType::FloatType,
67                        to: ValueType::IntType,
68                    })
69                }
70            }
71            Value::Bool(n) => Ok(*n as i64),
72            _ => match self.as_float() {
73                Ok(float) => Value::Float(float).as_int(),
74                // Overwrite error with the current types
75                Err(err) => match err {
76                    ErrorType::FailedCast { value, from, to: _ } => Err(ErrorType::FailedCast {
77                        value,
78                        from,
79                        to: ValueType::IntType,
80                    }),
81                    other => Err(other),
82                },
83            },
84        }
85    }
86
87    pub fn as_float(&self) -> EvalResult<FloatValue> {
88        match self {
89            Value::Float(n) => Ok(*n),
90            Value::Int(n) => Ok(*n as f64),
91            Value::Bool(n) => Ok(*n as i64 as f64),
92            Value::Complex(n) => {
93                if n.im == 0.0 {
94                    Ok(n.re)
95                } else {
96                    Err(ErrorType::FailedCast {
97                        value: self.clone(),
98                        from: ValueType::ComplexType,
99                        to: ValueType::FloatType,
100                    })
101                }
102            }
103            _ => match self.as_complex() {
104                Ok(complex) => Value::Complex(complex).as_float(),
105                // Overwrite error with the current types
106                Err(err) => match err {
107                    ErrorType::FailedCast { value, from, to: _ } => Err(ErrorType::FailedCast {
108                        value,
109                        from,
110                        to: ValueType::FloatType,
111                    }),
112                    other => Err(other),
113                },
114            },
115        }
116    }
117
118    pub fn as_complex(&self) -> EvalResult<ComplexValue> {
119        match self {
120            Value::Complex(n) => Ok(*n),
121            Value::Float(n) => Ok(Complex64::new(*n, 0.0)),
122            Value::Int(n) => Ok(Complex64::new(*n as f64, 0.0)),
123            Value::Bool(n) => Ok(Complex64::new(*n as i64 as f64, 0.0)),
124            Value::Vector(v) => {
125                if v.len() == 1 {
126                    v[0].as_complex()
127                } else {
128                    Err(ErrorType::FailedCast {
129                        value: self.clone(),
130                        from: ValueType::VectorType,
131                        to: ValueType::ComplexType,
132                    })
133                }
134            }
135        }
136    }
137
138    pub fn as_vector(&self) -> VectorValue {
139        match self {
140            Value::Vector(v) => v.clone(),
141            Value::Int(n) => vec![Value::Int(*n)],
142            Value::Float(n) => vec![Value::Float(*n)],
143            Value::Complex(n) => vec![Value::Complex(*n)],
144            Value::Bool(n) => vec![Value::Bool(*n)],
145        }
146    }
147
148    pub fn as_bool(&self) -> EvalResult<BoolValue> {
149        match self {
150            Value::Bool(n) => Ok(*n),
151            Value::Int(n) => {
152                if *n == 1 {
153                    Ok(true)
154                } else if *n == 0 {
155                    Ok(false)
156                } else {
157                    Err(ErrorType::FailedCast {
158                        value: self.clone(),
159                        from: ValueType::IntType,
160                        to: ValueType::BoolType,
161                    })
162                }
163            }
164            _ => match self.as_int() {
165                Ok(value) => Value::Int(value).as_bool(),
166                // Overwrite error with the current types
167                Err(err) => match err {
168                    ErrorType::FailedCast { value, from, to: _ } => Err(ErrorType::FailedCast {
169                        value,
170                        from,
171                        to: ValueType::BoolType,
172                    }),
173                    other => Err(other),
174                },
175            },
176        }
177    }
178
179    pub fn as_type(&self, valuetype: &ValueType) -> EvalResult<Value> {
180        match valuetype {
181            ValueType::BoolType => Ok(Value::Bool(self.as_bool()?)),
182            ValueType::IntType => Ok(Value::Int(self.as_int()?)),
183            ValueType::FloatType => Ok(Value::Float(self.as_float()?)),
184            ValueType::ComplexType => Ok(Value::Complex(self.as_complex()?)),
185            ValueType::VectorType => Ok(Value::Vector(self.as_vector())),
186        }
187    }
188
189    /// Creates a new value from a string.
190    pub fn from_string(string: String) -> EvalResult<Self> {
191        match &string[..] {
192            "true" => Ok(Value::Bool(true)),
193            "false" => Ok(Value::Bool(false)),
194            other => {
195                let mut other = String::from(other);
196
197                // Check for imaginary numbers
198                let i_count = other.matches("i").count();
199                if i_count != 0 {
200                    if i_count == 1 {
201                        other = String::from(other).replace("i", "");
202
203                        let other = if other == "" {
204                            String::from("1")
205                        } else {
206                            other
207                        };
208
209                        return Ok(Value::Complex(Complex64::new(
210                            0.0,
211                            match other.parse::<f64>() {
212                                Ok(value) => value,
213                                Err(_) => return Err(ErrorType::FailedParse { value: string }),
214                            },
215                        )));
216                    } else {
217                        return Err(ErrorType::FailedParse { value: string });
218                    }
219                }
220
221                // Check for floats
222                let count = other.matches(".").count();
223                if count != 0 {
224                    if count == 1 {
225                        match other.parse::<f64>() {
226                            Ok(value) => Ok(Value::Float(value)),
227                            Err(_) => Err(ErrorType::FailedParse { value: string }),
228                        }
229                    } else {
230                        Err(ErrorType::InvalidTokenPosition {
231                            token: TokenType::Dot,
232                        })
233                    }
234                } else {
235                    match other.parse::<i64>() {
236                        Ok(value) => Ok(Value::Int(value)),
237                        Err(_) => Err(ErrorType::FailedParse { value: string }),
238                    }
239                }
240            }
241        }
242    }
243
244    /// Tries to convert the value to the requested value-type. It returns the lowest
245    /// complexity value achieved.
246    pub fn try_as_type(&self, valuetype: ValueType) -> Value {
247        // If target complexity is same or higher, return the value
248        if self.to_type().complexity() <= valuetype.complexity() {
249            self.clone()
250        } else {
251            match valuetype {
252                ValueType::BoolType => match self.as_bool() {
253                    Ok(value) => Value::Bool(value),
254                    Err(_) => self.try_as_type(ValueType::IntType),
255                },
256                ValueType::IntType => match self.as_int() {
257                    Ok(value) => Value::Int(value),
258                    Err(_) => self.try_as_type(ValueType::FloatType),
259                },
260                ValueType::FloatType => match self.as_float() {
261                    Ok(value) => Value::Float(value),
262                    Err(_) => self.try_as_type(ValueType::ComplexType),
263                },
264                ValueType::ComplexType => match self.as_complex() {
265                    Ok(value) => Value::Complex(value),
266                    Err(_) => self.try_as_type(ValueType::VectorType),
267                },
268                ValueType::VectorType => Value::Vector(self.as_vector()),
269            }
270        }
271    }
272
273    pub fn round(&self, rounding: Rounding) -> Self {
274        match rounding {
275            Rounding::Round(precision) => {
276                let precision = precision.clamp(0, 12);
277                let factor = (10.0f64.powi(precision as i32)) as f64;
278                match self {
279                    Self::Float(v) => Value::Float((*v * factor).round() / factor),
280                    Self::Complex(c) => Value::Complex(Complex64::new(
281                        (c.re * factor).round() / factor,
282                        (c.im * factor).round() / factor,
283                    )),
284                    Self::Vector(vec) => {
285                        let mut out_vec = vec![];
286                        for val in vec {
287                            out_vec.push(val.round(rounding).clone());
288                        }
289                        Value::Vector(out_vec)
290                    }
291                    other => other.clone(),
292                }
293            }
294            _ => self.clone(),
295        }
296    }
297}
298
299impl From<BoolValue> for Value {
300    fn from(bool: BoolValue) -> Self {
301        Value::Bool(bool)
302    }
303}
304
305impl From<IntValue> for Value {
306    fn from(int: IntValue) -> Self {
307        Value::Int(int)
308    }
309}
310
311impl From<FloatValue> for Value {
312    fn from(float: FloatValue) -> Self {
313        Value::Float(float)
314    }
315}
316
317impl From<ComplexValue> for Value {
318    fn from(complex: ComplexValue) -> Self {
319        Value::Complex(complex)
320    }
321}
322
323impl<T> From<Vec<T>> for Value
324where
325    Value: From<T>,
326    T: Clone,
327{
328    fn from(vec: Vec<T>) -> Self {
329        Value::Vector(vec.iter().map(|v| Value::from(v.clone())).collect())
330    }
331}
332
333impl PartialEq for Value {
334    fn eq(&self, other: &Self) -> bool {
335        // This should never panics, as it converts the two operands
336        // to their highest complexity and return a Value::Bool
337        match self.clone().equal_to(other.clone()) {
338            Ok(bool_value) => bool_value.as_bool().unwrap(),
339            Err(_) => false,
340        }
341    }
342}