Skip to content

Commit ecc3d1c

Browse files
committed
add op feature for filler
1 parent 4e8037a commit ecc3d1c

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

derive/src/filler.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,46 @@ impl Filler {
141141
#[cfg(not(feature = "status"))]
142142
let status_impl = quote!();
143143

144+
#[cfg(feature = "op")]
145+
let op_impl = quote! {
146+
impl #generics core::ops::Shl<#name #generics> for #struct_name #generics #where_clause {
147+
type Output = Self;
148+
149+
fn shl(mut self, rhs: #name #generics) -> Self {
150+
struct_patch::traits::Filler::apply(&mut self, rhs);
151+
self
152+
}
153+
}
154+
155+
impl #generics core::ops::Add<Self> for #name #generics #where_clause {
156+
type Output = Self;
157+
158+
fn add(mut self, rhs: Self) -> Self {
159+
#(
160+
self.#native_value_field_names = self.#native_value_field_names + rhs.#native_value_field_names;
161+
)*
162+
#(
163+
self.#extendable_field_names.extend(rhs.#extendable_field_names.into_iter());
164+
)*
165+
#(
166+
if let Some(v) = self.#option_field_names {
167+
if let Some(u) = rhs.#option_field_names {
168+
self.#option_field_names = Some(v + &u);
169+
} else {
170+
self.#option_field_names = Some(v);
171+
}
172+
} else {
173+
self.#option_field_names = rhs.#option_field_names;
174+
}
175+
)*
176+
self
177+
}
178+
}
179+
};
180+
181+
#[cfg(not(feature = "op"))]
182+
let op_impl = quote!();
183+
144184
let filler_impl = quote! {
145185
impl #generics struct_patch::traits::Filler< #name #generics > for #struct_name #generics #where_clause {
146186
fn apply(&mut self, filler: #name #generics) {
@@ -177,6 +217,7 @@ impl Filler {
177217
#filler_struct
178218
#status_impl
179219
#filler_impl
220+
#op_impl
180221
})
181222
}
182223

lib/examples/filler.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use struct_patch::Filler;
55
use struct_patch::Status;
66

77
// NOTE: Default, Extend, IntoIterator, is_empty are required for extendable type
8-
#[derive(Debug, Default)]
8+
#[derive(Clone, Debug, Default)]
99
struct WrapVec {
1010
inner: Vec<usize>,
1111
}
@@ -30,8 +30,8 @@ impl WrapVec {
3030
}
3131
}
3232

33-
#[derive(Default, Filler)]
34-
#[filler(attribute(derive(Debug, Default)))]
33+
#[derive(Clone, Default, Filler)]
34+
#[filler(attribute(derive(Clone, Debug, Default)))]
3535
struct Item {
3636
field_complete: bool,
3737
// Will check the field is equal to the value to define the field is empty or not
@@ -127,4 +127,36 @@ fn main() {
127127
filler.field_int = 5;
128128
item.apply(filler);
129129
assert_eq!(item.field_int, 7);
130+
131+
#[cfg(feature = "op")]
132+
{
133+
let item = Item::default();
134+
135+
let mut filler1: ItemFiller = Item::new_empty_filler();
136+
filler1.field_int = 7;
137+
filler1.list = vec![1, 2];
138+
139+
let mut filler2: ItemFiller = Item::new_empty_filler();
140+
filler2.field_int = 8;
141+
filler2.list = vec![3, 4];
142+
filler2.maybe_field_string = Some("Something".into());
143+
144+
let final_item_from_added_fillers = item.clone() << (filler1.clone() + filler2.clone());
145+
146+
assert_eq!(final_item_from_added_fillers.field_int, 15);
147+
assert_eq!(final_item_from_added_fillers.list, vec![1, 2, 3, 4]);
148+
assert_eq!(
149+
final_item_from_added_fillers.maybe_field_string,
150+
Some("Something".into())
151+
);
152+
153+
let final_item_after_fillers_applied = item << filler1 << filler2;
154+
155+
assert_eq!(final_item_after_fillers_applied.field_int, 7);
156+
assert_eq!(final_item_after_fillers_applied.list, vec![1, 2]);
157+
assert_eq!(
158+
final_item_after_fillers_applied.maybe_field_string,
159+
Some("Something".into())
160+
);
161+
}
130162
}

0 commit comments

Comments
 (0)