brisk_it/
utils_impl.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use quote::ToTokens;

/// This trait is mainly used for Result<T,T> to return the
/// Ok or Err value.
pub trait Either<T> {
    /// Return the Ok or Err value.
    fn either(self) -> T;
}

impl<T> Either<T> for Result<T, T> {
    fn either(self) -> T {
        match self {
            Ok(a) => a,
            Err(a) => a,
        }
    }
}

/// This trait is used for Option to check if required properties have been set.
pub trait Required<T> {
    /// Check if the property was set, or return a missing property error.
    fn required(self, component_name: &syn::Ident, prop_name: &str) -> crate::Result<T>;
}

impl<T> Required<T> for Option<T> {
    fn required(self, component_name: &syn::Ident, prop_name: &str) -> crate::Result<T> {
        match self {
            Some(t) => Ok(t),
            None => Err(crate::errors::missing_property(component_name, prop_name)),
        }
    }
}

/// Check if `expr` is an expression or a component. If component, expand it to an expression.
pub fn component_or_expression(
    expr: &syn::Expr,
    manager: &crate::generator::Manager,
) -> proc_macro2::TokenStream {
    let expr_ts: proc_macro::TokenStream = expr.to_token_stream().into();
    let frame_comp = syn::parse::<crate::component::ComponentInput>(expr_ts);
    match frame_comp {
        Ok(frame_comp) => manager.generate(frame_comp).either(),
        Err(_) => expr.to_token_stream(),
    }
}

/// Make sure an expression is in a block
pub fn blockify(expr: syn::Expr) -> proc_macro2::TokenStream {
    match expr {
        syn::Expr::Block(e) => e.into_token_stream(),
        o => quote::quote! { { #o; } },
    }
}