From 1a91835abaa804aabf2e9bb45e9ab087274b8a18 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 12 Aug 2015 14:12:16 -0700 Subject: [PATCH] feat(net): impl downcast methods for NetworkStream (without + Send) Closes #521 --- src/net.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/net.rs b/src/net.rs index 5c8a1774f4..602bfee946 100644 --- a/src/net.rs +++ b/src/net.rs @@ -84,6 +84,61 @@ impl fmt::Debug for Box { } } +impl NetworkStream { + unsafe fn downcast_ref_unchecked(&self) -> &T { + mem::transmute(traitobject::data(self)) + } + + unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { + mem::transmute(traitobject::data_mut(self)) + } + + unsafe fn downcast_unchecked(self: Box) -> Box { + let raw: *mut NetworkStream = mem::transmute(self); + mem::transmute(traitobject::data_mut(raw)) + } +} + +impl NetworkStream { + /// Is the underlying type in this trait object a T? + #[inline] + pub fn is(&self) -> bool { + (*self).get_type() == TypeId::of::() + } + + /// If the underlying type is T, get a reference to the contained data. + #[inline] + pub fn downcast_ref(&self) -> Option<&T> { + if self.is::() { + Some(unsafe { self.downcast_ref_unchecked() }) + } else { + None + } + } + + /// If the underlying type is T, get a mutable reference to the contained + /// data. + #[inline] + pub fn downcast_mut(&mut self) -> Option<&mut T> { + if self.is::() { + Some(unsafe { self.downcast_mut_unchecked() }) + } else { + None + } + } + + /// If the underlying type is T, extract it. + #[inline] + pub fn downcast(self: Box) + -> Result, Box> { + if self.is::() { + Ok(unsafe { self.downcast_unchecked() }) + } else { + Err(self) + } + } +} + impl NetworkStream + Send { unsafe fn downcast_ref_unchecked(&self) -> &T { mem::transmute(traitobject::data(self))