diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-06-12 11:14:36 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-06-21 03:29:44 +0200 |
| commit | 22a73df71fc6d028d84b54776d6f5e7c7066da27 (patch) | |
| tree | 281bea3479beff4b45c4668690ada0d8280da637 /talpid_core | |
| parent | 14e3220ec993e2be9c6f37a65710b887bae5f49e (diff) | |
| download | mullvadvpn-22a73df71fc6d028d84b54776d6f5e7c7066da27.tar.xz mullvadvpn-22a73df71fc6d028d84b54776d6f5e7c7066da27.zip | |
Introduce plexmpsc and use in management interface
Diffstat (limited to 'talpid_core')
| -rw-r--r-- | talpid_core/src/lib.rs | 3 | ||||
| -rw-r--r-- | talpid_core/src/plexmpsc.rs | 76 |
2 files changed, 79 insertions, 0 deletions
diff --git a/talpid_core/src/lib.rs b/talpid_core/src/lib.rs index 5496d038ce..3ebb24d1ec 100644 --- a/talpid_core/src/lib.rs +++ b/talpid_core/src/lib.rs @@ -30,3 +30,6 @@ pub mod net; /// Abstracts over different VPN tunnel technologies pub mod tunnel; + +/// Multiplexing abstractions over `std::mpsc` +pub mod plexmpsc; diff --git a/talpid_core/src/plexmpsc.rs b/talpid_core/src/plexmpsc.rs new file mode 100644 index 0000000000..be1904bdb2 --- /dev/null +++ b/talpid_core/src/plexmpsc.rs @@ -0,0 +1,76 @@ +use std::marker::PhantomData; +use std::sync::mpsc; + +/// Abstraction over an `mpsc::Sender` that first converts the value to another type before sending. +#[derive(Debug, Clone)] +pub struct Sender<T, U> { + sender: mpsc::Sender<U>, + _marker: PhantomData<T>, +} + +impl<T, U> Sender<T, U> + where T: Into<U> +{ + /// Converts the `T` into a `U` and sends it on the channel. + pub fn send(&self, t: T) -> Result<(), mpsc::SendError<U>> { + self.sender.send(t.into()) + } +} + +impl<T, U> From<mpsc::Sender<U>> for Sender<T, U> + where T: Into<U> +{ + fn from(sender: mpsc::Sender<U>) -> Self { + Sender { + sender: sender, + _marker: PhantomData, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::mpsc; + use std::thread; + + #[derive(Debug, Eq, PartialEq)] + enum Inner { + One, + Two, + } + + #[derive(Debug, Eq, PartialEq)] + enum Outer { + Inner(Inner), + Other, + } + + impl From<Inner> for Outer { + fn from(o: Inner) -> Self { + Outer::Inner(o) + } + } + + #[test] + fn sender() { + let (tx, rx) = mpsc::channel::<Outer>(); + let inner_tx: Sender<Inner, Outer> = tx.clone().into(); + + tx.send(Outer::Other).unwrap(); + inner_tx.send(Inner::Two).unwrap(); + + assert_eq!(Outer::Other, rx.recv().unwrap()); + assert_eq!(Outer::Inner(Inner::Two), rx.recv().unwrap()); + } + + #[test] + fn send_between_thread() { + let (tx, rx) = mpsc::channel::<Outer>(); + let inner_tx: Sender<Inner, Outer> = tx.clone().into(); + + thread::spawn(move || { inner_tx.send(Inner::One).unwrap(); }); + + assert_eq!(Outer::Inner(Inner::One), rx.recv().unwrap()); + } +} |
