From 3e6637797960f825d7da333efec652c03f006b1e Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Thu, 14 Jul 2016 11:47:55 -0700 Subject: [PATCH] refactor(header): internalize traitobject and typeable --- Cargo.toml | 2 -- src/header/mod.rs | 48 +++++++++++++++++++++++++++++++++++++++-------- src/lib.rs | 2 -- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf55b4fb..38773a76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/header/mod.rs b/src/header/mod.rs index 64624e94..96eaa17b 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -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::() + } +} + +impl 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::(), len.get_type()); + assert_eq!(TypeId::of::(), agent.get_type()); + + let len: Box
= Box::new(len); + let agent: Box
= Box::new(agent); + + assert_eq!(TypeId::of::(), (*len).get_type()); + assert_eq!(TypeId::of::(), (*agent).get_type()); +} + #[doc(hidden)] pub trait HeaderClone { fn clone_box(&self) -> Box
; @@ -141,14 +165,22 @@ impl 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(&self) -> &T { - &*(traitobject::data(self) as *const T) + &*(mem::transmute::<*const _, (*const (), *const ())>(self).0 as *const T) } #[inline] unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { - &mut *(traitobject::data_mut(self) as *mut T) + &mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T) } } diff --git a/src/lib.rs b/src/lib.rs index 84dfe352..5329cb6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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]