This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew_macro/
use_transitive_state.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::{Expr, ExprClosure, ReturnType, Token, Type};
5
6#[derive(Debug)]
7pub struct TransitiveState {
8    closure: ExprClosure,
9    return_type: Type,
10    deps: Expr,
11}
12
13impl Parse for TransitiveState {
14    fn parse(input: ParseStream) -> syn::Result<Self> {
15        // Reads the deps.
16        let deps = input.parse()?;
17
18        input.parse::<Token![,]>().map_err(|e| {
19            syn::Error::new(
20                e.span(),
21                "this hook takes 2 arguments but 1 argument was supplied",
22            )
23        })?;
24
25        // Reads a closure.
26        let expr: Expr = input.parse()?;
27
28        let closure = match expr {
29            Expr::Closure(m) => m,
30            other => return Err(syn::Error::new_spanned(other, "expected closure")),
31        };
32
33        let return_type = match &closure.output {
34            ReturnType::Default => {
35                return Err(syn::Error::new_spanned(
36                    &closure,
37                    "You must specify a return type for this closure. This is used when the \
38                     closure is omitted from the client side rendering bundle.",
39                ))
40            }
41            ReturnType::Type(_rarrow, ty) => *ty.to_owned(),
42        };
43
44        if !input.is_empty() {
45            let maybe_trailing_comma = input.lookahead1();
46
47            if !maybe_trailing_comma.peek(Token![,]) {
48                return Err(maybe_trailing_comma.error());
49            }
50        }
51
52        Ok(Self {
53            closure,
54            return_type,
55            deps,
56        })
57    }
58}
59
60impl TransitiveState {
61    pub fn to_token_stream_with_closure(&self) -> TokenStream {
62        let deps = &self.deps;
63        let rt = &self.return_type;
64        let closure = &self.closure;
65
66        quote! {
67            ::yew::functional::use_transitive_state::<#rt, _, _>(#deps, #closure)
68        }
69    }
70
71    // Expose a hook for the client side.
72    //
73    // The closure is stripped from the client side.
74    pub fn to_token_stream_without_closure(&self) -> TokenStream {
75        let deps = &self.deps;
76        let rt = &self.return_type;
77
78        quote! {
79            ::yew::functional::use_transitive_state::<#rt, _>(#deps)
80        }
81    }
82}