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 54 55 56 57 58 59 60 61
//! This module provides macro `assign!` to allow mutating instance with declarative flavor //! //! The motivation of this macro is to enable programmer to document a sequence of mutations instance fields as initialization by writing it in a declarative way. `assign!` macro also allows programmer to skip defining fields that has default value. Such case are used when a dependency is exposing an non-exhaustive struct #![no_std] /// Mutate instance with declarative flavor /// /// /// # Usage /// ``` /// # #[macro_use] extern crate assign; /// # fn main() { /// #[non_exhaustive] /// struct SomeStruct { /// a: u32, /// b: Option<f32>, /// c: String, /// } /// impl SomeStruct { /// fn new() -> SomeStruct { /// SomeStruct { /// a: 1u32, /// b: None, /// c: String::from("old"), /// } /// } /// } /// /// // In order to treat the mutation of field `a` and `c` as an initialization /// // Use assign to mutate field in declarative flavor, thus avoiding the risk inserting code /// // between the line that defines a field and the line that defines the other /// // Note that field `b` is skipped /// let instance = assign!(SomeStruct::new(), { /// a: 2u32, /// c: String::from("new"), /// }); /// /// // Equivalent /// let instance2 = { /// let mut item = SomeStruct::new(); /// item.a = 2u32; /// item.c = String::from("new"); /// item /// }; /// /// assert_eq!(instance.a, instance2.a); /// assert_eq!(instance.b, instance2.b); /// assert_eq!(&instance.c, &instance2.c); /// # } /// ``` /// #[macro_export] macro_rules! assign { ($initial_value:expr, { $($field:ident: $value:expr),+ $(,)? }) => ({ let mut item = $initial_value; $( item.$field = $value; )+ item }) }