Skip to content

Commit 3e66377

Browse files
committed
refactor(header): internalize traitobject and typeable
1 parent 6d54a4d commit 3e66377

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ rotor = "0.6"
2020
rustc-serialize = "0.3"
2121
spmc = "0.2"
2222
time = "0.1"
23-
traitobject = "0.0.1"
24-
typeable = "0.1"
2523
unicase = "1.0"
2624
url = "1.0"
2725
vecio = "0.1"

src/header/mod.rs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,12 @@
7575
//! }
7676
//! }
7777
//! ```
78-
use std::any::Any;
78+
use std::any::{Any, TypeId};
7979
use std::borrow::{Cow, ToOwned};
80-
//use std::collections::HashMap;
81-
//use std::collections::hash_map::{Iter, Entry};
8280
use std::iter::{FromIterator, IntoIterator};
8381
use std::{mem, fmt};
8482

85-
use {httparse, traitobject};
86-
use typeable::Typeable;
83+
use httparse;
8784
use unicase::UniCase;
8885

8986
use self::internals::{Item, VecMap, Entry};
@@ -108,7 +105,7 @@ pub mod parsing;
108105
///
109106
/// This trait represents the construction and identification of headers,
110107
/// and contains trait-object unsafe methods.
111-
pub trait Header: HeaderClone + Any + Typeable + Send + Sync {
108+
pub trait Header: HeaderClone + Any + GetType + Send + Sync {
112109
/// Returns the name of the header field this belongs to.
113110
///
114111
/// This will become an associated constant once available.
@@ -128,6 +125,33 @@ pub trait Header: HeaderClone + Any + Typeable + Send + Sync {
128125
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result;
129126
}
130127

128+
#[doc(hidden)]
129+
pub trait GetType: Any {
130+
#[inline(always)]
131+
fn get_type(&self) -> TypeId {
132+
TypeId::of::<Self>()
133+
}
134+
}
135+
136+
impl<T: Any> GetType for T {}
137+
138+
#[test]
139+
fn test_get_type() {
140+
use ::header::{ContentLength, UserAgent};
141+
142+
let len = ContentLength(5);
143+
let agent = UserAgent("hyper".to_owned());
144+
145+
assert_eq!(TypeId::of::<ContentLength>(), len.get_type());
146+
assert_eq!(TypeId::of::<UserAgent>(), agent.get_type());
147+
148+
let len: Box<Header + Send + Sync> = Box::new(len);
149+
let agent: Box<Header + Send + Sync> = Box::new(agent);
150+
151+
assert_eq!(TypeId::of::<ContentLength>(), (*len).get_type());
152+
assert_eq!(TypeId::of::<UserAgent>(), (*agent).get_type());
153+
}
154+
131155
#[doc(hidden)]
132156
pub trait HeaderClone {
133157
fn clone_box(&self) -> Box<Header + Send + Sync>;
@@ -141,14 +165,22 @@ impl<T: Header + Clone> HeaderClone for T {
141165
}
142166

143167
impl Header + Send + Sync {
168+
// A trait object looks like this:
169+
//
170+
// TraitObject { data: *mut (), vtable: *mut () }
171+
//
172+
// So, we transmute &Trait into a (*mut (), *mut ()). This depends on the
173+
// order the compiler has chosen to represent a TraitObject.
174+
//
175+
// It has been assured that this order will be stable.
144176
#[inline]
145177
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
146-
&*(traitobject::data(self) as *const T)
178+
&*(mem::transmute::<*const _, (*const (), *const ())>(self).0 as *const T)
147179
}
148180

149181
#[inline]
150182
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
151-
&mut *(traitobject::data_mut(self) as *mut T)
183+
&mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T)
152184
}
153185
}
154186

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ extern crate unicase;
2929
extern crate httparse;
3030
extern crate rotor;
3131
extern crate spmc;
32-
extern crate traitobject;
33-
extern crate typeable;
3432
extern crate vecio;
3533

3634
#[macro_use]

0 commit comments

Comments
 (0)