zng_var/
expr.rs

1///<span data-del-macro-root></span> New variable from an expression with interpolated vars.
2///
3/// # Interpolation
4///
5/// Other variables can be interpolated by quoting the var with `#{..}`. When
6/// an expression contains other interpolated vars the expression var updates when
7/// any of the interpolated vars update.
8///
9/// # Examples
10///
11/// ```
12/// # use zng_var::*;
13/// let var_a = var(10);
14/// let var_b = var(10);
15/// let name = "var_eq";
16/// let var_eq = expr_var! {
17///     let eq = #{var_a} == #{var_b};
18///     println!("{} updated: {} == {}: {}", name, #{var_a}, #{var_b}, eq);
19///     eq
20/// };
21/// ```
22///
23/// In the example a `var_eq` var of type `impl Var<bool>` is created. When either `var_a` or `var_b` are set
24/// the value of `var_eq` is updated. Normal variables like `name` are moved in, like a closure capture.
25///
26/// # Capture Mode
27///
28/// The expression operates like a closure that captures by `move`. Both the interpolated variables and any
29/// other `let` binding referenced from the scope are moved into the resulting variable.
30///
31/// # Interpolation
32///
33/// Variable interpolation is done by quoting the variable with `#{<var-expr>}`, the braces are required.
34///
35/// The `<var-expr>` is evaluated before *capturing* starts so if you interpolate `#{var_a.clone()}` `var_a`
36/// will still be available after the `expr_var` call. Equal `<var-expr>` only evaluate once.
37///
38/// # Expansion
39///
40/// The expression is transformed into different types of vars depending on the number of interpolated variables.
41///
42/// ##### No Variables
43///
44/// An expression with no interpolation is simply evaluated into a var using [`IntoVar`].
45///
46/// ##### Single Variable
47///
48/// An expression with a single variable is transformed in a [`map`] operation, unless the expression
49/// is only the variable without any extra operation.
50///
51/// ##### Multiple Variables
52///
53/// An expression with multiple variables is transformed into a [`merge_var!`] call.
54///
55/// [`Var::get`]: crate::Var::get
56/// [`map`]: crate::Var::map
57/// [`IntoVar`]: crate::IntoVar
58/// [`merge_var!`]: crate::merge_var
59#[macro_export]
60macro_rules! expr_var {
61    ($($expr:tt)+) => {
62        $crate::types::__expr_var! { $crate, $($expr)+ }
63    };
64}
65
66#[doc(hidden)]
67pub use zng_var_proc_macros::expr_var as __expr_var;
68
69use super::{IntoVar, Var, VarValue};
70
71#[doc(hidden)]
72pub fn expr_var_into<T: VarValue>(expr: impl IntoVar<T>) -> impl Var<T> {
73    expr.into_var()
74}
75
76#[doc(hidden)]
77pub fn expr_var_as<T: VarValue>(var: impl Var<T>) -> impl Var<T> {
78    var
79}
80
81#[doc(hidden)]
82pub fn expr_var_map<I: VarValue, O: VarValue>(input: impl Var<I>, map: impl FnMut(&I) -> O + Send + 'static) -> impl Var<O> {
83    input.map(map)
84}