chore(all): Move downcasting to a stable implementation.

This commit is contained in:
Jonathan Reem
2015-04-02 13:26:47 -07:00
parent 3dc8e7d6ff
commit 320d10d50d
4 changed files with 20 additions and 17 deletions

View File

@@ -22,6 +22,8 @@ rustc-serialize = "*"
time = "*" time = "*"
unicase = "*" unicase = "*"
url = "*" url = "*"
traitobject = "*"
typeable = "*"
[dev-dependencies] [dev-dependencies]
env_logger = "*" env_logger = "*"

View File

@@ -6,14 +6,12 @@
//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others. //! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
use std::any::Any; use std::any::Any;
use std::borrow::{Cow, ToOwned}; use std::borrow::{Cow, ToOwned};
use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::{Iter, Entry}; use std::collections::hash_map::{Iter, Entry};
use std::iter::{FromIterator, IntoIterator}; use std::iter::{FromIterator, IntoIterator};
use std::raw::TraitObject; use std::{mem, fmt};
use std::{mem, raw};
use httparse; use {httparse, traitobject};
use unicase::UniCase; use unicase::UniCase;
use self::internals::Item; use self::internals::Item;
@@ -76,12 +74,12 @@ impl<T: HeaderFormat + Send + Sync + Clone> HeaderClone for T {
impl HeaderFormat + Send + Sync { impl HeaderFormat + Send + Sync {
#[inline] #[inline]
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T { unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
mem::transmute(mem::transmute::<&HeaderFormat, raw::TraitObject>(self).data) mem::transmute(traitobject::data(self))
} }
#[inline] #[inline]
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
mem::transmute(mem::transmute::<&mut HeaderFormat, raw::TraitObject>(self).data) mem::transmute(traitobject::data_mut(self))
} }
} }

View File

@@ -5,6 +5,7 @@
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
//! # Hyper //! # Hyper
//!
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It //! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant //! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP. //! layer over "stringly-typed" HTTP.
@@ -134,6 +135,8 @@ extern crate cookie;
extern crate unicase; extern crate unicase;
extern crate httparse; extern crate httparse;
extern crate num_cpus; extern crate num_cpus;
extern crate traitobject;
extern crate typeable;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

View File

@@ -5,7 +5,6 @@ use std::io::{self, Read, Write};
use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener};
use std::mem; use std::mem;
use std::path::Path; use std::path::Path;
use std::raw::{self, TraitObject};
use std::sync::Arc; use std::sync::Arc;
use std::marker::Reflect; use std::marker::Reflect;
@@ -15,6 +14,9 @@ use openssl::ssl::SslMethod::Sslv23;
use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed}; use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed};
use openssl::x509::X509FileType; use openssl::x509::X509FileType;
use typeable::Typeable;
use {traitobject};
macro_rules! try_some { macro_rules! try_some {
($expr:expr) => (match $expr { ($expr:expr) => (match $expr {
Some(val) => { return Err(val); }, Some(val) => { return Err(val); },
@@ -62,7 +64,7 @@ impl<'a, N: NetworkListener + 'a> Iterator for NetworkConnections<'a, N> {
/// An abstraction over streams that a Server can utilize. /// An abstraction over streams that a Server can utilize.
pub trait NetworkStream: Read + Write + Any + StreamClone + Send { pub trait NetworkStream: Read + Write + Any + StreamClone + Send + Typeable {
/// Get the remote address of the underlying connection. /// Get the remote address of the underlying connection.
fn peer_addr(&mut self) -> io::Result<SocketAddr>; fn peer_addr(&mut self) -> io::Result<SocketAddr>;
} }
@@ -100,31 +102,29 @@ impl Clone for Box<NetworkStream + Send> {
impl NetworkStream + Send { impl NetworkStream + Send {
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T { unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
mem::transmute(mem::transmute::<&NetworkStream, mem::transmute(traitobject::data(self))
raw::TraitObject>(self).data)
} }
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
mem::transmute(mem::transmute::<&mut NetworkStream, mem::transmute(traitobject::data_mut(self))
raw::TraitObject>(self).data)
} }
unsafe fn downcast_unchecked<T: 'static>(self: Box<NetworkStream + Send>) -> Box<T> { unsafe fn downcast_unchecked<T: 'static>(self: Box<NetworkStream + Send>) -> Box<T> {
mem::transmute(mem::transmute::<Box<NetworkStream + Send>, let raw: *mut NetworkStream = mem::transmute(self);
raw::TraitObject>(self).data) mem::transmute(traitobject::data_mut(raw))
} }
} }
impl NetworkStream + Send { impl NetworkStream + Send {
/// Is the underlying type in this trait object a T? /// Is the underlying type in this trait object a T?
#[inline] #[inline]
pub fn is<T: Reflect + 'static>(&self) -> bool { pub fn is<T: Any>(&self) -> bool {
self.get_type_id() == TypeId::of::<T>() (*self).get_type() == TypeId::of::<T>()
} }
/// If the underlying type is T, get a reference to the contained data. /// If the underlying type is T, get a reference to the contained data.
#[inline] #[inline]
pub fn downcast_ref<T: Reflect + 'static>(&self) -> Option<&T> { pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
if self.is::<T>() { if self.is::<T>() {
Some(unsafe { self.downcast_ref_unchecked() }) Some(unsafe { self.downcast_ref_unchecked() })
} else { } else {