You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.2 KiB
Rust

use crate::template::Params;
use syn::{
braced, parenthesized,
parse::{discouraged::Speculative, Parse, ParseStream},
token, Expr, Path, Token,
};
use super::{Body, Component, NamedParam};
impl Parse for Body {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut elements = Vec::new();
while !input.is_empty() {
elements.push(input.parse()?);
}
Ok(Self { elements })
}
}
impl Parse for Component {
fn parse(input: ParseStream) -> syn::Result<Self> {
let name: Path = input.parse()?;
let params = if input.lookahead1().peek(token::Paren) {
Some(Params::parse(input)?)
} else {
None
};
let body = if input.lookahead1().peek(token::Brace) {
let inner;
braced!(inner in input);
Some(inner.parse()?)
} else {
None
};
Ok(Self { name, params, body })
}
}
impl Parse for Params {
fn parse(input: ParseStream) -> syn::Result<Self> {
let inner;
parenthesized!(inner in input);
if inner.is_empty() {
Ok(Self::Named(Vec::new()))
} else {
let ahead = inner.fork();
match ahead.parse_terminated(NamedParam::parse, Token![,]) {
Ok(vals) => {
let x = Ok(Self::Named(vals.into_iter().collect()));
inner.advance_to(&ahead);
x
}
Err(_) => {
let vals = inner.parse_terminated(Expr::parse, Token![,])?;
Ok(Self::Anon(vals.into_iter().collect()))
}
}
}
}
}
impl Parse for NamedParam {
fn parse(input: ParseStream) -> syn::Result<Self> {
let name: syn::Ident = input.parse()?;
if name.to_string().starts_with("__uwui") {
// TODO: we need to walk through the entire syntax tree, not just param names
return Err(syn::Error::new(
name.span(),
"Names starting with `__uwui` are reserved",
));
}
let colon = input.parse()?;
let val = input.parse()?;
Ok(Self { name, colon, val })
}
}