refactor(header): internalize traitobject and typeable
This commit is contained in:
@@ -20,8 +20,6 @@ rotor = "0.6"
|
||||
rustc-serialize = "0.3"
|
||||
spmc = "0.2"
|
||||
time = "0.1"
|
||||
traitobject = "0.0.1"
|
||||
typeable = "0.1"
|
||||
unicase = "1.0"
|
||||
url = "1.0"
|
||||
vecio = "0.1"
|
||||
|
||||
@@ -75,15 +75,12 @@
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use std::any::Any;
|
||||
use std::any::{Any, TypeId};
|
||||
use std::borrow::{Cow, ToOwned};
|
||||
//use std::collections::HashMap;
|
||||
//use std::collections::hash_map::{Iter, Entry};
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::{mem, fmt};
|
||||
|
||||
use {httparse, traitobject};
|
||||
use typeable::Typeable;
|
||||
use httparse;
|
||||
use unicase::UniCase;
|
||||
|
||||
use self::internals::{Item, VecMap, Entry};
|
||||
@@ -108,7 +105,7 @@ pub mod parsing;
|
||||
///
|
||||
/// This trait represents the construction and identification of headers,
|
||||
/// 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.
|
||||
///
|
||||
/// 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;
|
||||
}
|
||||
|
||||
#[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)]
|
||||
pub trait HeaderClone {
|
||||
fn clone_box(&self) -> Box<Header + Send + Sync>;
|
||||
@@ -141,14 +165,22 @@ impl<T: Header + Clone> HeaderClone for T {
|
||||
}
|
||||
|
||||
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]
|
||||
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]
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ extern crate unicase;
|
||||
extern crate httparse;
|
||||
extern crate rotor;
|
||||
extern crate spmc;
|
||||
extern crate traitobject;
|
||||
extern crate typeable;
|
||||
extern crate vecio;
|
||||
|
||||
#[macro_use]
|
||||
|
||||
Reference in New Issue
Block a user