openpql_pql_parser/ast/
num.rs1use super::{Display, Error, LalrError, Loc, NumValueFloat, NumValueInt, str};
2
3#[derive(Clone, PartialEq, derive_more::From, derive_more::Debug)]
4#[debug("{}", self.inner)]
5pub struct Num {
6 pub inner: NumValue,
7 pub loc: (Loc, Loc),
8}
9
10impl From<(NumValueFloat, (Loc, Loc))> for Num {
11 fn from((val, loc): (NumValueFloat, (Loc, Loc))) -> Self {
12 Self {
13 inner: val.into(),
14 loc,
15 }
16 }
17}
18
19impl From<(NumValueInt, (Loc, Loc))> for Num {
20 fn from((val, loc): (NumValueInt, (Loc, Loc))) -> Self {
21 Self {
22 inner: val.into(),
23 loc,
24 }
25 }
26}
27
28impl<'input> TryFrom<(&'input str, (Loc, Loc), bool)> for Num {
32 type Error = LalrError<'input>;
33
34 fn try_from(
35 (src, loc, is_float): (&'input str, (Loc, Loc), bool),
36 ) -> Result<Self, Self::Error> {
37 if is_float {
38 Ok((src.parse::<NumValueFloat>().unwrap(), loc).into())
39 } else {
40 src.parse::<NumValueInt>().map_or_else(
41 |_| Err(Error::InvalidNumericValue(loc).into()),
42 |v| Ok((v, loc).into()),
43 )
44 }
45 }
46}
47
48#[derive(Clone, Copy, Debug, PartialEq, derive_more::From, Display)]
49pub enum NumValue {
50 #[display("{_0}")]
51 Int(NumValueInt),
52 #[display("{_0}")]
53 Float(NumValueFloat),
54}
55
56#[cfg(test)]
57mod tests {
58
59 use super::*;
60 use crate::*;
61
62 fn assert_num<T>(src: &str, expected: T)
63 where
64 NumValue: From<T>,
65 {
66 let loc_start = 0;
67 let loc_end = src.len();
68 assert_eq!(
69 parse_num(src),
70 Ok((NumValue::from(expected), (loc_start, loc_end)).into())
71 );
72 }
73
74 #[test]
75 fn test_num() {
76 assert_num("0", 0);
77 assert_num("-1", -1);
78 assert_num("-1.5", -1.5);
79 assert_num("-.5", -0.5);
80 assert_num(".5", 0.5);
81 }
82
83 #[test]
84 fn test_err() {
85 let toobig = format!("{}0", NumValueInt::MAX);
86 assert_eq!(
87 parse_num(&toobig),
88 Err(Error::InvalidNumericValue((0, toobig.len())))
89 );
90 }
91
92 #[test]
93 fn test_dbg() {
94 assert_eq!(format!("{:?}", Num::from((-123, (0, 1)))), "-123");
95 }
96}