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#[derive(Clone)]
17pub enum Lit {
18 Bool(LitBool),
20
21 Hex(LitHexStr),
23
24 Number(LitNumber),
26
27 Str(LitStr),
29
30 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}