syn_solidity/lit/
mod.rs

1use crate::{kw, Spanned};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5    parse::{Lookahead1, Parse, ParseStream},
6    LitBool, Result,
7};
8
9mod number;
10pub use number::{LitDenominated, LitNumber, SubDenomination};
11
12mod str;
13pub use self::str::{HexStr, LitHexStr, LitStr, LitUnicodeStr, UnicodeStr};
14
15/// A Solidity literal such as a string or integer or boolean.
16#[derive(Clone)]
17pub enum Lit {
18    /// A boolean literal: `true` or `false`.
19    Bool(LitBool),
20
21    /// A hex string literal: `hex"1234"`.
22    Hex(LitHexStr),
23
24    /// An integer or fixed-point number literal: `1` or `1.0`.
25    Number(LitNumber),
26
27    /// A string literal.
28    Str(LitStr),
29
30    /// A unicode string literal.
31    Unicode(LitUnicodeStr),
32}
33
34impl fmt::Debug for Lit {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.write_str("Lit::")?;
37        match self {
38            Self::Bool(lit) => lit.fmt(f),
39            Self::Hex(lit) => lit.fmt(f),
40            Self::Number(lit) => lit.fmt(f),
41            Self::Str(lit) => lit.fmt(f),
42            Self::Unicode(lit) => lit.fmt(f),
43        }
44    }
45}
46
47impl Parse for Lit {
48    fn parse(input: ParseStream<'_>) -> Result<Self> {
49        let lookahead = input.lookahead1();
50        if lookahead.peek(syn::LitStr) {
51            input.parse().map(Self::Str)
52        } else if LitNumber::peek(&lookahead) {
53            input.parse().map(Self::Number)
54        } else if lookahead.peek(LitBool) {
55            input.parse().map(Self::Bool)
56        } else if lookahead.peek(kw::unicode) {
57            input.parse().map(Self::Unicode)
58        } else if lookahead.peek(kw::hex) {
59            input.parse().map(Self::Hex)
60        } else {
61            Err(lookahead.error())
62        }
63    }
64}
65
66impl Spanned for Lit {
67    fn span(&self) -> Span {
68        match self {
69            Self::Bool(lit) => lit.span(),
70            Self::Hex(lit) => lit.span(),
71            Self::Number(lit) => lit.span(),
72            Self::Str(lit) => lit.span(),
73            Self::Unicode(lit) => lit.span(),
74        }
75    }
76
77    fn set_span(&mut self, span: Span) {
78        match self {
79            Self::Bool(lit) => lit.set_span(span),
80            Self::Hex(lit) => lit.set_span(span),
81            Self::Number(lit) => lit.set_span(span),
82            Self::Str(lit) => lit.set_span(span),
83            Self::Unicode(lit) => lit.set_span(span),
84        }
85    }
86}
87
88impl Lit {
89    pub fn peek(lookahead: &Lookahead1<'_>) -> bool {
90        lookahead.peek(syn::Lit) || lookahead.peek(kw::unicode) || lookahead.peek(kw::hex)
91    }
92}