use crate::{kw, Spanned};
use proc_macro2::Span;
use std::fmt;
use syn::{
parse::{Lookahead1, Parse, ParseStream},
LitBool, Result,
};
mod number;
pub use number::{LitDenominated, LitNumber, SubDenomination};
mod str;
pub use self::str::{HexStr, LitHexStr, LitStr, LitUnicodeStr, UnicodeStr};
#[derive(Clone)]
pub enum Lit {
Bool(LitBool),
Hex(LitHexStr),
Number(LitNumber),
Str(LitStr),
Unicode(LitUnicodeStr),
}
impl fmt::Debug for Lit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Lit::")?;
match self {
Self::Bool(lit) => lit.fmt(f),
Self::Hex(lit) => lit.fmt(f),
Self::Number(lit) => lit.fmt(f),
Self::Str(lit) => lit.fmt(f),
Self::Unicode(lit) => lit.fmt(f),
}
}
}
impl Parse for Lit {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let lookahead = input.lookahead1();
if lookahead.peek(syn::LitStr) {
input.parse().map(Self::Str)
} else if LitNumber::peek(&lookahead) {
input.parse().map(Self::Number)
} else if lookahead.peek(LitBool) {
input.parse().map(Self::Bool)
} else if lookahead.peek(kw::unicode) {
input.parse().map(Self::Unicode)
} else if lookahead.peek(kw::hex) {
input.parse().map(Self::Hex)
} else {
Err(lookahead.error())
}
}
}
impl Spanned for Lit {
fn span(&self) -> Span {
match self {
Self::Bool(lit) => lit.span(),
Self::Hex(lit) => lit.span(),
Self::Number(lit) => lit.span(),
Self::Str(lit) => lit.span(),
Self::Unicode(lit) => lit.span(),
}
}
fn set_span(&mut self, span: Span) {
match self {
Self::Bool(lit) => lit.set_span(span),
Self::Hex(lit) => lit.set_span(span),
Self::Number(lit) => lit.set_span(span),
Self::Str(lit) => lit.set_span(span),
Self::Unicode(lit) => lit.set_span(span),
}
}
}
impl Lit {
pub fn peek(lookahead: &Lookahead1<'_>) -> bool {
lookahead.peek(syn::Lit) || lookahead.peek(kw::unicode) || lookahead.peek(kw::hex)
}
}