#[derive(CopyWith)]
{
// Attributes available to this derive:
#[copy]
}
Expand description
Add a copy_with
function for decorated type, copy value from another Self
if that value is
not default
value.
For the following struct, generate:
struct MyStruct {
foo1: i8,
foo2: String,
foo3: Option<String>,
}
impl MyStruct {
fn copy_with(&mut self, other: &Self) {
if other.foo1 != i8::default() {
self.foo1 = other.foo1.clone();
}
if other.foo2 != String::default() {
self.foo2 = other.foo2.clone();
}
if other.foo3 != Option::default() {
self.foo3 = other.foo3.clone();
}
}
}
§Usage
- Add
#[derive(CopyWith)]
to struct. - Because types and implementations are unknown in macro expanding, add
#[copy]
attribute to the field which also#[derived(CopyWith)]
so that will use that impl instead of default value. - Notice that the new value and cloned so all the fields can not be reference or borrowed type.
§Example:
use racros::CopyWith;
#[derive(Clone, Default, CopyWith)]
struct MyStruct {
foo1: i8,
foo2: String,
foo3: Option<String>,
}
#[derive(CopyWith)]
struct MyStruct2 {
#[copy]
bar1: MyStruct,
}
let s1 = MyStruct::default();
let mut s11 = MyStruct::default();
let s2 = MyStruct {
foo1: 64,
foo2: String::from("hello world"),
foo3: Some(String::from("hello world")),
};
let mut s21 = MyStruct {
foo1: 64,
foo2: String::from("hello world"),
foo3: Some(String::from("hello world")),
};
s11.copy_with(&s2);
assert_eq!(s11.foo1, s2.foo1);
assert_eq!(s11.foo2, s2.foo2);
assert_eq!(s11.foo3, s2.foo3);
s21.copy_with(&s1);
assert_eq!(s21.foo1, s2.foo1);
assert_eq!(s21.foo2, s2.foo2);
assert_eq!(s21.foo3, s2.foo3);
let mut s31 = MyStruct2 {
bar1: MyStruct::default(),
};
let s32 = MyStruct2 {
bar1: MyStruct {
foo1: 64,
foo2: String::from("hello world"),
foo3: Some(String::from("hello world")),
},
};
s31.copy_with(&s32);
assert_eq!(s31.bar1.foo1, s2.foo1);
assert_eq!(s31.bar1.foo2, s2.foo2);
assert_eq!(s31.bar1.foo3, s2.foo3);