litcheck_filecheck/expr/
value.rs1use 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}