refactor(header): internalize traitobject and typeable
This commit is contained in:
		| @@ -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" | ||||||
|   | |||||||
| @@ -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) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user