experimental_reactive/
activator.rs

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
21/// Represents activator which have an opportunity to become connected one
22pub 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
38/// Activator connected to `Source`
39pub 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
49/// Activator connected to `Slot`
50pub 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
60/// Fully connected activator
61pub 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	/// transfer portion of data from connected `Source` to `Slot`
65	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}