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
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 })
|
|
}
|
|
}
|