1use proc_macro2::TokenStream as TokenStream2;
12use syn::Token;
13use syn::parse::{ParseStream, Parser, Result};
14
15use crate::ir::TeksiRoot;
16
17mod body;
18mod cursor;
19mod element;
20mod property;
21mod structural;
22
23pub fn parse_root(tokens: TokenStream2) -> Result<TeksiRoot> {
24 Parser::parse2(parse_root_impl, tokens)
25}
26
27fn parse_root_impl(input: ParseStream) -> Result<TeksiRoot> {
28 let ctx = if input.peek(syn::Ident) && input.peek2(Token![=>]) {
32 let ident: syn::Ident = input.parse()?;
33 let _arrow: Token![=>] = input.parse()?;
34 Some(ident)
35 } else {
36 None
37 };
38
39 let root = element::parse_element(input)?;
40
41 if !input.is_empty() {
42 return Err(input.error(
43 "expected end of teksu! input — the root element must be the only top-level element",
44 ));
45 }
46
47 Ok(TeksiRoot { ctx, root })
48}
49
50pub(crate) use body::parse_body;
52#[allow(unused_imports)]
53pub(crate) use cursor::{peek_binding, peek_element_start, peek_escape};
54pub(crate) use element::parse_element;
55pub(crate) use property::parse_property_args;
56pub(crate) use structural::{parse_for, parse_if, parse_match, parse_spread, peek_spread};