Macro dyn_context::free_lifetimes

source ·
macro_rules! free_lifetimes {
    (
        $(#[$attr:meta])*
        $vis:vis struct $name:ident $($token:tt)*
    ) => { ... };
}
Expand description

Creates structure, allowing to pack several references into a one reference to a 'static type.

Accepts input in the following form:

$(#[$attr:meta])*
$vis:vis struct $name:ident $(<$generics> $(where $where_clause)?)? {
    $($(
        $field:ident : $($lt:lifetime ref | $lt:lifetime mut | const) $ty:ty
    ),+ $(,)?)?
}

In Rust, lifetimes are intrusive, and sometimes it can lead to an inadequately complex code. Moreover, in some cases it can lead to an impossible code, means code so complex, so it can not make to compiles, even it is logically meaningful. (Such situations could occur because Rust does not support existential types with infinite parameters list.)

The free_lifetimes! macro allows to “compress” several lifetimes into a one.

For example, you can pack together two str references and use them with a code, requiring a 'static type:

free_lifetimes! {
    struct DoubleStr {
        str_1: 'str_1 ref str,
        str_2: 'str_2 ref str
    }
}

fn call_back<T: 'static, R>(t: &T, callback: impl FnOnce(&T) -> R) -> R {
    callback(t)
}

let s_1 = String::from("str1");
let s_2 = String::from("str2");
let r = DoubleStrBuilder {
    str_1: &s_1[1..],
    str_2: &s_2[2..]
}.build_and_then(|double_str| call_back(double_str, |double_str| {
    format!("{}{}", double_str.str_1(), double_str.str_2())
}));
assert_eq!(r, "tr1r2");