Merge pull request #864 from hyperium/less-deps

refactor(header): internalize traitobject and typeable
This commit is contained in:
Sean McArthur
2016-07-14 20:36:43 -07:00
committed by GitHub
3 changed files with 40 additions and 12 deletions

View File

@@ -20,8 +20,6 @@ rotor = "0.6"
rustc-serialize = "0.3" rustc-serialize = "0.3"
spmc = "0.2" spmc = "0.2"
time = "0.1" time = "0.1"
traitobject = "0.0.1"
typeable = "0.1"
unicase = "1.0" unicase = "1.0"
url = "1.0" url = "1.0"
vecio = "0.1" vecio = "0.1"

View File

@@ -75,15 +75,12 @@
//! } //! }
//! } //! }
//! ``` //! ```
use std::any::Any; use std::any::{Any, TypeId};
use std::borrow::{Cow, ToOwned}; use std::borrow::{Cow, ToOwned};
//use std::collections::HashMap;
//use std::collections::hash_map::{Iter, Entry};
use std::iter::{FromIterator, IntoIterator}; use std::iter::{FromIterator, IntoIterator};
use std::{mem, fmt}; use std::{mem, fmt};
use {httparse, traitobject}; use httparse;
use typeable::Typeable;
use unicase::UniCase; use unicase::UniCase;
use self::internals::{Item, VecMap, Entry}; use self::internals::{Item, VecMap, Entry};
@@ -108,7 +105,7 @@ pub mod parsing;
/// ///
/// This trait represents the construction and identification of headers, /// This trait represents the construction and identification of headers,
/// and contains trait-object unsafe methods. /// and contains trait-object unsafe methods.
pub trait Header: HeaderClone + Any + Typeable + Send + Sync { pub trait Header: HeaderClone + Any + GetType + Send + Sync {
/// Returns the name of the header field this belongs to. /// Returns the name of the header field this belongs to.
/// ///
/// This will become an associated constant once available. /// This will become an associated constant once available.
@@ -128,6 +125,33 @@ pub trait Header: HeaderClone + Any + Typeable + Send + Sync {
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result; fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result;
} }
#[doc(hidden)]
pub trait GetType: Any {
#[inline(always)]
fn get_type(&self) -> TypeId {
TypeId::of::<Self>()
}
}
impl<T: Any> GetType for T {}
#[test]
fn test_get_type() {
use ::header::{ContentLength, UserAgent};
let len = ContentLength(5);
let agent = UserAgent("hyper".to_owned());
assert_eq!(TypeId::of::<ContentLength>(), len.get_type());
assert_eq!(TypeId::of::<UserAgent>(), agent.get_type());
let len: Box<Header + Send + Sync> = Box::new(len);
let agent: Box<Header + Send + Sync> = Box::new(agent);
assert_eq!(TypeId::of::<ContentLength>(), (*len).get_type());
assert_eq!(TypeId::of::<UserAgent>(), (*agent).get_type());
}
#[doc(hidden)] #[doc(hidden)]
pub trait HeaderClone { pub trait HeaderClone {
fn clone_box(&self) -> Box<Header + Send + Sync>; fn clone_box(&self) -> Box<Header + Send + Sync>;
@@ -141,14 +165,22 @@ impl<T: Header + Clone> HeaderClone for T {
} }
impl Header + Send + Sync { impl Header + Send + Sync {
// A trait object looks like this:
//
// TraitObject { data: *mut (), vtable: *mut () }
//
// So, we transmute &Trait into a (*mut (), *mut ()). This depends on the
// order the compiler has chosen to represent a TraitObject.
//
// It has been assured that this order will be stable.
#[inline] #[inline]
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T { unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
&*(traitobject::data(self) as *const T) &*(mem::transmute::<*const _, (*const (), *const ())>(self).0 as *const T)
} }
#[inline] #[inline]
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
&mut *(traitobject::data_mut(self) as *mut T) &mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T)
} }
} }

View File

@@ -29,8 +29,6 @@ extern crate unicase;
extern crate httparse; extern crate httparse;
extern crate rotor; extern crate rotor;
extern crate spmc; extern crate spmc;
extern crate traitobject;
extern crate typeable;
extern crate vecio; extern crate vecio;
#[macro_use] #[macro_use]