From e82ddf5bd68334ff90776c42d968cf1c6bf9b5f2 Mon Sep 17 00:00:00 2001 From: Philipp Mildenberger Date: Sat, 17 Feb 2024 00:13:30 +0100 Subject: [PATCH] Support arrays (`[impl ViewSequence; N]`) as `ViewSequence`s Adds the blanket impl `impl ViewSequence for [VT; N]` Allows for example something like this: ```rust fn my_tab(impl View) -> impl View {..} h_stack(["Tab 1", "Tab 2", "Tab 3"].map(my_tab)) ``` --- crates/xilem_core/src/sequence.rs | 45 +++++++++++++++++++++++++++++++ examples/hello.rs | 10 +++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/crates/xilem_core/src/sequence.rs b/crates/xilem_core/src/sequence.rs index 60444b7c5..a93cb59b3 100644 --- a/crates/xilem_core/src/sequence.rs +++ b/crates/xilem_core/src/sequence.rs @@ -283,6 +283,51 @@ macro_rules! generate_viewsequence_trait { } } + impl> $viewseq for [VT; N] { + type State = [VT::State; N]; + + fn build(&self, cx: &mut Cx, elements: &mut Vec<$pod>) -> Self::State { + self.each_ref().map(|vs| vs.build(cx, elements)) + } + + fn rebuild( + &self, + cx: &mut $cx, + prev: &Self, + state: &mut Self::State, + elements: &mut $crate::VecSplice<$pod>, + ) -> $changeflags { + self.iter() + .enumerate() + .map(|(i, vs)| vs.rebuild(cx, &prev[i], &mut state[i], elements)) + .fold(ChangeFlags::empty(), |changes_acc, changes| { + changes_acc | changes + }) + } + + fn message( + &self, + id_path: &[Id], + state: &mut Self::State, + message: Box, + app_state: &mut T, + ) -> $crate::MessageResult { + let mut result = $crate::MessageResult::Stale(message); + for (child, child_state) in self.iter().zip(state) { + if let $crate::MessageResult::Stale(message) = result { + result = child.message(id_path, child_state, message, app_state); + } else { + break; + } + } + result + } + + fn count(&self, _state: &Self::State) -> usize { + N + } + } + /// This trait marks a type a #[doc = concat!(stringify!($view), ".")] /// diff --git a/examples/hello.rs b/examples/hello.rs index 1de432ab6..ae025e376 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -16,7 +16,7 @@ fn app_logic(data: &mut AppData) -> impl View { println!("clicked"); data.count += 1; }), - h_stack(( + h_stack([ button("decrease", |data: &mut AppData| { println!("clicked decrease"); data.count -= 1; @@ -25,10 +25,10 @@ fn app_logic(data: &mut AppData) -> impl View { println!("clicked reset"); data.count = 0; }), - switch(data.is_on, |data: &mut AppData, value: bool| { - data.is_on = value - }), - )), + ]), + switch(data.is_on, |data: &mut AppData, value: bool| { + data.is_on = value + }), )) .with_spacing(20.0) }