Skip to main content

rustidy_ast/
lifetime.rs

1//! Lifetime
2
3// Imports
4use {
5	super::token,
6	rustidy_ast_util::{IdentifierOrKeyword, NonKeywordIdentifier},
7	rustidy_format::{Format, Formattable, WhitespaceFormat},
8	rustidy_parse::{Parse, Parser, ParserTag},
9	rustidy_print::Print,
10	rustidy_util::Whitespace,
11};
12
13/// `Lifetime`
14#[derive(PartialEq, Eq, Clone, Debug)]
15#[derive(serde::Serialize, serde::Deserialize)]
16#[derive(Parse, Formattable, Format, Print)]
17pub struct Lifetime(LifetimeToken);
18
19/// `LIFETIME_TOKEN`
20#[derive(PartialEq, Eq, Clone, Debug)]
21#[derive(serde::Serialize, serde::Deserialize)]
22#[derive(Parse, Formattable, Format, Print)]
23pub enum LifetimeToken {
24	IdentOrKeyword(QuoteNotQuote<IdentifierOrKeyword>),
25	Underscore(QuoteNotQuote<token::Underscore>),
26	// TODO: `r#'ident`
27}
28
29/// `LIFETIME_OR_LABEL`
30#[derive(PartialEq, Eq, Clone, Debug)]
31#[derive(serde::Serialize, serde::Deserialize)]
32#[derive(Parse, Formattable, Format, Print)]
33pub enum LifetimeOrLabel {
34	IdentOrKeyword(QuoteNotQuote<NonKeywordIdentifier>),
35	Underscore(QuoteNotQuote<token::Underscore>),
36	// TODO: `r#'ident`
37}
38
39#[derive(PartialEq, Eq, Clone, Debug)]
40#[derive(serde::Serialize, serde::Deserialize)]
41#[derive(Parse, Formattable, Format, Print)]
42#[parse(name = "a lifetime token")]
43#[parse(error(name = SuffixQuote, fmt = "Unexpected `'`"))]
44#[parse(and_try_with = Self::check_suffix_quote)]
45pub struct QuoteNotQuote<T> {
46	pub quote: token::Quote,
47	#[parse(with_tag = ParserTag::SkipWhitespace)]
48	#[format(prefix_ws = Whitespace::REMOVE)]
49	pub value: T,
50}
51
52impl<T: Parse> QuoteNotQuote<T> {
53	pub fn check_suffix_quote(&mut self, parser: &mut Parser) -> Result<(), QuoteNotQuoteError<T>> {
54		// If we parse a `'` right after the value, then this is actually a character literal
55		// and so we reject it.
56		if parser
57			.with_tag(
58				ParserTag::SkipWhitespace,
59				Parser::try_parse::<token::Quote>
60			)
61			.map_err(QuoteNotQuoteError::Quote)?
62			.is_ok() {
63			return Err(QuoteNotQuoteError::SuffixQuote);
64		}
65
66		Ok(())
67	}
68}