reign_view 0.2.1

Opinionated Fullstack Web Framework in Rust
Documentation
use super::{Expr, Tokenize, ViewFields};
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
    parse::{Parse, ParseStream, Result},
    token::Colon,
    Error, Type,
};

pub struct ExprType {
    pub expr: Box<Expr>,
    pub colon_token: Colon,
    pub ty: Box<Type>,
}

impl Parse for ExprType {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut expr: Expr = input.parse()?;
        loop {
            match expr {
                Expr::Type(inner) => return Ok(inner),
                Expr::Group(next) => expr = *next.expr,
                _ => {
                    return Err(Error::new(
                        Span::call_site(),
                        "expected type ascription expression",
                    ))
                }
            }
        }
    }
}

impl Tokenize for ExprType {
    fn tokenize(&self, tokens: &mut TokenStream, idents: &mut ViewFields, scopes: &ViewFields) {
        let mut ty_tokens = TokenStream::new();

        self.ty.to_tokens(&mut ty_tokens);

        if let Expr::Path(path) = &*self.expr {
            if let Some(ident) = path.path.get_ident() {
                if !scopes.contains(&ident) {
                    idents.insert(ident.clone(), Some(ty_tokens));

                    tokens.append_all(quote! {
                        self.#ident
                    });
                    return;
                }
            }
        }

        self.expr.tokenize(tokens, idents, scopes);
    }
}