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