1use super::*;
19use crate::error::NoError;
20
21pub trait Connectable<State, Action, Target> {
27 type ConnectionError;
29
30 type Connections<'a>: IntoIterator<Item = Result<(Action, State), Self::ConnectionError>> + 'a
31 where
32 Self: 'a,
33 Self::ConnectionError: 'a,
34 State: 'a,
35 Action: 'a,
36 Target: 'a;
37
38 fn connect<'a>(&'a self, from_state: State, to_target: &'a Target) -> Self::Connections<'a>
39 where
40 Self: 'a,
41 Self::ConnectionError: 'a,
42 State: 'a,
43 Action: 'a,
44 Target: 'a;
45}
46
47impl<State, Action, Target> Connectable<State, Action, Target> for () {
50 type ConnectionError = NoError;
51 type Connections<'a>
52 = [Result<(Action, State), NoError>; 0]
53 where
54 Action: 'a,
55 State: 'a,
56 Target: 'a;
57
58 fn connect<'a>(&'a self, _: State, _: &'a Target) -> Self::Connections<'a>
59 where
60 Self: 'a,
61 Self::ConnectionError: 'a,
62 State: 'a,
63 Action: 'a,
64 Target: 'a,
65 {
66 []
67 }
68}
69
70impl<Base, Prop, State, Action, Target> Connectable<State, Action, Target> for Chained<Base, Prop>
71where
72 Base: Connectable<State, Action, Target>,
73 Base::ConnectionError: Into<Prop::ConnectionError>,
74 Prop: Connectable<State, Action, Target>,
75 State: Clone,
76{
77 type ConnectionError = Prop::ConnectionError;
78 type Connections<'a>
79 = ChainedConnections<'a, Base, Prop, State, Action, Target>
80 where
81 Self: 'a,
82 Self::ConnectionError: 'a,
83 State: 'a,
84 Action: 'a,
85 Target: 'a;
86
87 fn connect<'a>(&'a self, from_state: State, to_target: &'a Target) -> Self::Connections<'a>
88 where
89 Self: 'a,
90 Self::ConnectionError: 'a,
91 State: 'a,
92 Action: 'a,
93 Target: 'a,
94 {
95 ChainedConnections::<Base, Prop, State, Action, Target> {
96 base_connections: self.base.connect(from_state.clone(), to_target).into_iter(),
97 prop_connections: self.prop.connect(from_state, to_target).into_iter(),
98 }
99 }
100}
101
102pub struct ChainedConnections<'a, Base, Prop, State, Action, Target>
103where
104 Base: Connectable<State, Action, Target> + 'a,
105 Prop: Connectable<State, Action, Target> + 'a,
106 Base::ConnectionError: 'a,
107 State: 'a,
108 Action: 'a,
109 Target: 'a,
110{
111 base_connections: <Base::Connections<'a> as IntoIterator>::IntoIter,
112 prop_connections: <Prop::Connections<'a> as IntoIterator>::IntoIter,
113}
114
115impl<'a, Base, Prop, State, Action, Target> Iterator
116 for ChainedConnections<'a, Base, Prop, State, Action, Target>
117where
118 Base: Connectable<State, Action, Target> + 'a,
119 Prop: Connectable<State, Action, Target> + 'a,
120 Base::ConnectionError: 'a + Into<Prop::ConnectionError>,
121 State: 'a,
122 Action: 'a,
123 Target: 'a,
124{
125 type Item = Result<(Action, State), Prop::ConnectionError>;
126 fn next(&mut self) -> Option<Self::Item> {
127 if let Some(next) = self.base_connections.next() {
128 let next = next.map_err(Into::into);
129 return Some(next);
130 }
131
132 self.prop_connections.next()
133 }
134}