use core::fmt;
use proc_macro2::{Span, TokenStream, TokenTree};
use syn::Token;
use crate::static_buffer::StaticBuffer;
pub(crate) struct MatchArm {
pub(crate) attr: Vec<syn::Attribute>,
pub(crate) pattern: syn::Pat,
pub(crate) condition: Option<syn::Expr>,
pub(crate) block: TokenStream,
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum Delimiter {
Parenthesis,
Brace,
Bracket,
}
impl Delimiter {
pub(crate) fn encode_open(self, output: &mut StaticBuffer) {
let c = match self {
Self::Parenthesis => '(',
Self::Brace => '{',
Self::Bracket => '[',
};
output.push(c);
}
pub(crate) fn encode_close(self, output: &mut StaticBuffer) {
let c = match self {
Self::Parenthesis => ')',
Self::Brace => '}',
Self::Bracket => ']',
};
output.push(c);
}
}
pub(crate) enum LiteralName<'a> {
Ident(&'a str),
Char(char),
}
impl fmt::Display for LiteralName<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
LiteralName::Ident(ident) => ident.fmt(f),
LiteralName::Char(c) => write!(f, "{c:?}"),
}
}
}
pub(crate) enum Name {
Const(Token![const]),
Ident(String),
Char(char),
}
impl Name {
pub(crate) fn as_literal_name(&self) -> LiteralName<'_> {
match self {
Name::Const(..) => LiteralName::Ident("const"),
Name::Ident(name) => LiteralName::Ident(name.as_str()),
Name::Char(c) => LiteralName::Char(*c),
}
}
}
impl q::ToTokens for Name {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Name::Const(t) => t.to_tokens(tokens),
Name::Ident(name) => name.to_tokens(tokens),
Name::Char(c) => c.to_tokens(tokens),
}
}
}
#[derive(Debug)]
pub(crate) enum ControlKind {
Space,
Push,
Line,
}
#[derive(Debug)]
pub(crate) struct Control {
pub(crate) kind: ControlKind,
pub(crate) span: Span,
}
impl Control {
pub(crate) fn from_char(span: Span, c: char) -> Option<Self> {
match c {
' ' => Some(Self {
kind: ControlKind::Space,
span,
}),
'\n' => Some(Self {
kind: ControlKind::Line,
span,
}),
'\r' => Some(Self {
kind: ControlKind::Push,
span,
}),
_ => None,
}
}
}
pub(crate) enum Ast {
Tree {
tt: TokenTree,
},
String {
has_eval: bool,
stream: TokenStream,
},
Quoted {
s: syn::LitStr,
},
Literal {
string: String,
},
DelimiterOpen {
delimiter: Delimiter,
},
DelimiterClose {
delimiter: Delimiter,
},
Control {
control: Control,
},
EvalIdent {
ident: syn::Ident,
},
Eval {
expr: syn::Expr,
},
Scope {
binding: Option<syn::Ident>,
content: TokenStream,
},
Loop {
pattern: Box<syn::Pat>,
expr: Box<syn::Expr>,
join: Option<TokenStream>,
stream: TokenStream,
},
Condition {
condition: syn::Expr,
then_branch: TokenStream,
else_branch: Option<TokenStream>,
},
Let {
name: syn::Pat,
expr: syn::Expr,
},
Match {
condition: syn::Expr,
arms: Vec<MatchArm>,
},
}