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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use super::*;
use crate::{pipe::InnerPipe, widget::WidgetBuilder};

/// Trait specify what child a multi child widget can have, and the target type
/// after widget compose its child.
pub trait MultiWithChild<C, M: ?Sized> {
  type Target;
  fn with_child(self, child: C, ctx: &BuildCtx) -> Self::Target;
}

pub struct MultiPair<P> {
  pub parent: P,
  pub children: Vec<Widget>,
}

trait FillVec<M: ?Sized> {
  fn fill_vec(self, vec: &mut Vec<Widget>, ctx: &BuildCtx);
}

crate::widget::multi_build_replace_impl_include_self! {
  impl<W: {#}> FillVec<dyn {#}> for W {
    #[inline]
    fn fill_vec(self, vec: &mut Vec<Widget>, ctx: &BuildCtx) { vec.push(self.build(ctx)) }
  }

  impl<W> FillVec<&dyn {#}> for W
  where
    W: IntoIterator,
    W::Item: {#},
  {
    #[inline]
    fn fill_vec(self, vec: &mut Vec<Widget>, ctx: &BuildCtx) {
      vec.extend(self.into_iter().map(|w| w.build(ctx)))
    }
  }
}

crate::widget::multi_build_replace_impl_include_self! {
  impl<T, V> FillVec<&&dyn {#}> for T
  where
    T: InnerPipe<Value=V>,
    V: IntoIterator + 'static,
    V::Item: {#},
  {
    fn fill_vec(self, vec: &mut Vec<Widget>, ctx: &BuildCtx) {
      self.build_multi(vec, |v, ctx| v.build(ctx), ctx);
    }
  }
}

impl<M: ?Sized, P, C> MultiWithChild<C, M> for P
where
  P: MultiParent,
  C: FillVec<M>,
{
  type Target = MultiPair<P>;

  fn with_child(self, child: C, ctx: &BuildCtx) -> Self::Target {
    let mut children = vec![];
    child.fill_vec(&mut children, ctx);
    MultiPair { parent: self, children }
  }
}

impl<M: ?Sized, C, P> MultiWithChild<C, M> for MultiPair<P>
where
  C: FillVec<M>,
{
  type Target = Self;
  #[inline]
  fn with_child(mut self, child: C, ctx: &BuildCtx) -> Self::Target {
    child.fill_vec(&mut self.children, ctx);
    self
  }
}

impl<P: MultiParent> WidgetBuilder for MultiPair<P> {
  fn build(self, ctx: &BuildCtx) -> Widget {
    let MultiPair { parent, children } = self;
    parent.compose_children(children.into_iter(), ctx)
  }
}