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