litcheck_filecheck/expr/
value.rs

1use std::borrow::Cow;
2
3use crate::expr::{Expr, Number, NumberFormat};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum Value<'a> {
7    Undef,
8    Str(Cow<'a, str>),
9    Num(Expr),
10}
11impl<'a> Value<'a> {
12    pub fn unwrap_string(&self) -> Cow<'a, str> {
13        match self {
14            Self::Undef => Cow::Borrowed(""),
15            Self::Str(s) => s.clone(),
16            Self::Num(Expr::Num(n)) => Cow::Owned(format!("{n}")),
17            Self::Num(expr) => panic!("cannot unwrap expression as string: {expr:?}"),
18        }
19    }
20
21    pub fn as_number(&self) -> Option<Number> {
22        match self {
23            Value::Num(Expr::Num(num)) => Some(num.clone()),
24            _ => None,
25        }
26    }
27}
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq)]
30pub enum ValueType {
31    String,
32    Number(NumberFormat),
33}
34impl PartialOrd for ValueType {
35    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
36        Some(self.cmp(other))
37    }
38}
39impl Ord for ValueType {
40    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
41        use core::cmp::Ordering;
42        match (self, other) {
43            (Self::String, Self::String) => Ordering::Equal,
44            (Self::String, _) => Ordering::Less,
45            (_, Self::String) => Ordering::Greater,
46            (Self::Number(a), Self::Number(b)) => {
47                if a == b {
48                    Ordering::Equal
49                } else {
50                    let ap = a.precision();
51                    let bp = b.precision();
52                    if ap == 0 && bp > 0 {
53                        Ordering::Greater
54                    } else if ap > 0 && bp == 0 {
55                        Ordering::Less
56                    } else {
57                        ap.cmp(&bp)
58                            .then_with(|| a.discriminant().cmp(&b.discriminant()))
59                    }
60                }
61            }
62        }
63    }
64}