feat(core): compose effect collections
Support Vec<T: IntoEffect> and [T; N] batches so dynamic reusable partial updates compose inside the existing effect model without a broad IntoIterator blanket impl. req: canonical_authoring/003
This commit is contained in:
@@ -850,6 +850,22 @@ impl<T: IntoEffect> IntoEffect for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoEffect> IntoEffect for Vec<T> {
|
||||
fn append_to(self, ops: &mut Vec<Effect>) {
|
||||
for effect in self {
|
||||
effect.append_to(ops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoEffect, const N: usize> IntoEffect for [T; N] {
|
||||
fn append_to(self, ops: &mut Vec<Effect>) {
|
||||
for effect in self {
|
||||
effect.append_to(ops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_tuple_into_effect {
|
||||
($($name:ident $idx:tt),+) => {
|
||||
impl<$($name),+> IntoEffect for ($($name,)+)
|
||||
|
||||
@@ -38,6 +38,30 @@ fn optional_effects_compose_into_batches() {
|
||||
assert_eq!(batch.ops[0], count.text(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn effect_collections_compose_into_batches() {
|
||||
// req: canonical_authoring/003
|
||||
let rows = KeyedSlot::<u64, String>::new(2);
|
||||
let summary = Slot::<u32>::new(3);
|
||||
let notice = Slot::<String>::new(4);
|
||||
|
||||
let dynamic_rows = [7, 8]
|
||||
.into_iter()
|
||||
.map(|id| rows.replace_text(id, format!("todo {id}")))
|
||||
.collect::<Vec<_>>();
|
||||
let fixed_notices = [notice.text("Saved"), notice.text("Synced")];
|
||||
|
||||
let batch =
|
||||
(dynamic_rows, Some(summary.text(2)), fixed_notices).into_batch(BuildFingerprint(42));
|
||||
|
||||
assert_eq!(batch.ops.len(), 5);
|
||||
assert_eq!(batch.ops[0], rows.replace_text(7, String::from("todo 7")));
|
||||
assert_eq!(batch.ops[1], rows.replace_text(8, String::from("todo 8")));
|
||||
assert_eq!(batch.ops[2], summary.text(2));
|
||||
assert_eq!(batch.ops[3], notice.text("Saved"));
|
||||
assert_eq!(batch.ops[4], notice.text("Synced"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keyed_slot_replace_uses_scoped_resource_ref() {
|
||||
let todos = KeyedSlot::<u64, String>::new(9);
|
||||
|
||||
Reference in New Issue
Block a user