syn_solidity/lit/
number.rs1use crate::{kw, Spanned};
2use proc_macro2::{Literal, Span};
3use std::{fmt, str::FromStr};
4use syn::{
5 parse::{Lookahead1, Parse, ParseStream},
6 LitFloat, LitInt, Result,
7};
8
9#[derive(Clone)]
13pub enum LitNumber {
14 Int(LitInt),
15 Float(LitFloat),
16}
17
18impl fmt::Debug for LitNumber {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 Self::Int(lit) => lit.fmt(f),
22 Self::Float(lit) => lit.fmt(f),
23 }
24 }
25}
26
27impl Parse for LitNumber {
28 fn parse(input: ParseStream<'_>) -> Result<Self> {
29 let lookahead = input.lookahead1();
30 if lookahead.peek(LitInt) {
31 input.parse().map(Self::Int)
32 } else if lookahead.peek(LitFloat) {
33 input.parse().map(Self::Float)
34 } else {
35 Err(lookahead.error())
36 }
37 }
38}
39
40impl Spanned for LitNumber {
41 fn span(&self) -> Span {
42 match self {
43 Self::Int(lit) => lit.span(),
44 Self::Float(lit) => lit.span(),
45 }
46 }
47
48 fn set_span(&mut self, span: Span) {
49 match self {
50 Self::Int(lit) => lit.set_span(span),
51 Self::Float(lit) => lit.set_span(span),
52 }
53 }
54}
55
56impl LitNumber {
57 pub fn new_int(repr: &str, span: Span) -> Self {
58 Self::Int(LitInt::new(repr, span))
59 }
60
61 pub fn new_fixed(repr: &str, span: Span) -> Self {
62 Self::Float(LitFloat::new(repr, span))
63 }
64
65 pub fn peek(lookahead: &Lookahead1<'_>) -> bool {
66 lookahead.peek(LitInt) || lookahead.peek(LitFloat)
67 }
68
69 pub fn base10_digits(&self) -> &str {
71 match self {
72 Self::Int(lit) => lit.base10_digits(),
73 Self::Float(lit) => lit.base10_digits(),
74 }
75 }
76
77 pub fn base10_parse<N>(&self) -> Result<N>
83 where
84 N: FromStr,
85 N::Err: fmt::Display,
86 {
87 match self {
88 Self::Int(lit) => lit.base10_parse(),
89 Self::Float(lit) => lit.base10_parse(),
90 }
91 }
92
93 pub fn suffix(&self) -> &str {
94 match self {
95 Self::Int(lit) => lit.suffix(),
96 Self::Float(lit) => lit.suffix(),
97 }
98 }
99
100 pub fn token(&self) -> Literal {
101 match self {
102 Self::Int(lit) => lit.token(),
103 Self::Float(lit) => lit.token(),
104 }
105 }
106}
107
108#[derive(Clone, Debug)]
109pub struct LitDenominated {
110 pub number: LitNumber,
111 pub denom: SubDenomination,
112}
113
114impl Parse for LitDenominated {
115 fn parse(input: ParseStream<'_>) -> Result<Self> {
116 Ok(Self { number: input.parse()?, denom: input.parse()? })
117 }
118}
119
120impl Spanned for LitDenominated {
121 fn span(&self) -> Span {
122 let span = self.number.span();
123 span.join(self.denom.span()).unwrap_or(span)
124 }
125
126 fn set_span(&mut self, span: Span) {
127 self.number.set_span(span);
128 self.denom.set_span(span);
129 }
130}
131
132kw_enum! {
133 pub enum SubDenomination {
135 Wei(kw::wei),
136 Gwei(kw::gwei),
137 Ether(kw::ether),
138
139 Seconds(kw::seconds),
140 Minutes(kw::minutes),
141 Hours(kw::hours),
142 Days(kw::days),
143 Weeks(kw::weeks),
144 Years(kw::years),
145 }
146}
147
148impl SubDenomination {
149 pub const fn value(self) -> u64 {
151 match self {
153 Self::Wei(..) => 1,
154 Self::Gwei(..) => 1_000_000_000,
155 Self::Ether(..) => 1_000_000_000_000_000_000,
156
157 Self::Seconds(..) => 1,
158 Self::Minutes(..) => 60,
159 Self::Hours(..) => 3_600,
160 Self::Days(..) => 86_400,
161 Self::Weeks(..) => 604_800,
162 Self::Years(..) => 31_536_000,
163 }
164 }
165}