1use std::marker::PhantomData;
2
3use reactive::*;
4
5pub use self::ActivateError::*;
6
7#[derive(PartialOrd, Ord, PartialEq, Eq, Debug)]
8pub enum ActivateError<T> {
9 SourceActivationError(SourceError),
10 SlotActivationError(SlotError<T>),
11 NotConnected,
12}
13
14impl<T> From<SourceError> for ActivateError<T> {
15 fn from(error: SourceError) -> Self { SourceActivationError(error) }
16}
17impl<T> From<SlotError<T>> for ActivateError<T> {
18 fn from(error: SlotError<T>) -> Self { SlotActivationError(error) }
19}
20
21pub struct DisconnectedActivator;
23
24impl<T, S> Sink<T, S> for DisconnectedActivator where S: Source<T> {
25 type Connected = SourceConnectedActivator<T, S>;
26 fn connect_source(self, src: S) -> SourceConnectedActivator<T, S> {
27 SourceConnectedActivator(src, PhantomData)
28 }
29}
30
31impl<T, S> Signal<T, S> for DisconnectedActivator where S: Slot<T> {
32 type Connected = SlotConnectedActivator<T, S>;
33 fn connect_slot(self, slot: S) -> SlotConnectedActivator<T, S> {
34 SlotConnectedActivator(slot, PhantomData)
35 }
36}
37
38pub struct SourceConnectedActivator<T, S>(S, PhantomData<(T, S)>) where S: Source<T>;
40
41impl<T, S, U> Signal<T, S> for SourceConnectedActivator<T, U> where S: Slot<T>, U: Source<T> {
42 type Connected = ConnectedActivator<T, U, S>;
43 fn connect_slot(self, slot: S) -> ConnectedActivator<T, U, S> {
44 ConnectedActivator(self.0, slot, PhantomData)
45 }
46}
47
48
49pub struct SlotConnectedActivator<T, S>(S, PhantomData<(T, S)>) where S: Slot<T>;
51
52impl<T, S, U> Sink<T, S> for SlotConnectedActivator<T, U> where S: Source<T>, U: Slot<T> {
53 type Connected = ConnectedActivator<T, S, U>;
54 fn connect_source(self, src: S) -> ConnectedActivator<T, S, U> {
55 ConnectedActivator(src, self.0, PhantomData)
56 }
57}
58
59
60pub struct ConnectedActivator<T, S, U>(S, U, PhantomData<(T, S, U)>) where S: Source<T>, U: Slot<T>;
62
63impl<T, S, U> ConnectedActivator<T, S, U> where S: Source<T>, U: Slot<T> {
64 pub fn activate(&self) -> Result<(), ActivateError<T>> {
66 let (ref src, ref slt) = (&self.0, &self.1);
67 let value = try!(src.pull());
68 try!(slt.push(value));
69 Ok(())
70 }
71}
72
73
74pub struct Activator<T, S, U> where S: Slot<T>, U: Source<T> {
75 slot: Option<S>,
76 source: Option<U>,
77 pd: PhantomData<T>
78}
79
80
81impl<'a, T, S, U> Signal<T, S> for &'a mut Activator<T, S, U> where S: Slot<T>, U: Source<T> {
82 type Connected = ();
83 fn connect_slot(self, slot: S) {
84 self.slot = Some(slot);
85 }
86}
87
88impl<'a, T, S, U> Sink<T, U> for &'a mut Activator<T, S, U> where S: Slot<T>, U: Source<T> {
89 type Connected = ();
90 fn connect_source(self, source: U) {
91 self.source = Some(source);
92 }
93}
94
95impl<T, S, U> Activator<T, S, U> where S: Slot<T>, U: Source<T> {
96 pub fn new() -> Activator<T, S, U> {
97 Activator{slot: None, source: None, pd: PhantomData}
98 }
99
100 pub fn activate(&self) -> Result<(), ActivateError<T>> {
101 if let (&Some(ref src), &Some(ref slt)) = (&self.source, &self.slot) {
102 let value = try!(src.pull());
103 try!(slt.push(value));
104 Ok(())
105 } else {
106 Err(NotConnected)
107 }
108 }
109}