diff --git a/core/src/transport/mod.rs b/core/src/transport/mod.rs index 25d3be0f..c15e6d58 100644 --- a/core/src/transport/mod.rs +++ b/core/src/transport/mod.rs @@ -42,8 +42,11 @@ pub mod memory; pub mod timeout; pub mod upgrade; +mod optional; + pub use self::choice::OrTransport; pub use self::memory::MemoryTransport; +pub use self::optional::OptionalTransport; pub use self::upgrade::Upgrade; /// A transport provides connection-oriented communication between two peers diff --git a/core/src/transport/optional.rs b/core/src/transport/optional.rs new file mode 100644 index 00000000..283b50d7 --- /dev/null +++ b/core/src/transport/optional.rs @@ -0,0 +1,77 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use crate::transport::{Transport, TransportError}; +use multiaddr::Multiaddr; + +/// Transport that is possibly disabled. +/// +/// An `OptionalTransport` is a wrapper around an `Option`. If it is disabled (read: contains +/// `None`), then any attempt to dial or listen will return `MultiaddrNotSupported`. If it is +/// enabled (read: contains `Some`), then dialing and listening will be handled by the inner +/// transport. +#[derive(Debug, Copy, Clone)] +pub struct OptionalTransport(Option); + +impl OptionalTransport { + /// Builds an `OptionalTransport` with the given transport in an enabled + /// state. + pub fn some(inner: T) -> OptionalTransport { + OptionalTransport(Some(inner)) + } + + /// Builds a disabled `OptionalTransport`. + pub fn none() -> OptionalTransport { + OptionalTransport(None) + } +} + +impl From for OptionalTransport { + fn from(inner: T) -> Self { + OptionalTransport(Some(inner)) + } +} + +impl Transport for OptionalTransport +where + T: Transport, +{ + type Output = T::Output; + type Error = T::Error; + type Listener = T::Listener; + type ListenerUpgrade = T::ListenerUpgrade; + type Dial = T::Dial; + + fn listen_on(self, addr: Multiaddr) -> Result> { + if let Some(inner) = self.0 { + inner.listen_on(addr) + } else { + Err(TransportError::MultiaddrNotSupported(addr)) + } + } + + fn dial(self, addr: Multiaddr) -> Result> { + if let Some(inner) = self.0 { + inner.dial(addr) + } else { + Err(TransportError::MultiaddrNotSupported(addr)) + } + } +}