75
75
//! }
76
76
//! }
77
77
//! ```
78
- use std:: any:: Any ;
78
+ use std:: any:: { Any , TypeId } ;
79
79
use std:: borrow:: { Cow , ToOwned } ;
80
- //use std::collections::HashMap;
81
- //use std::collections::hash_map::{Iter, Entry};
82
80
use std:: iter:: { FromIterator , IntoIterator } ;
83
81
use std:: { mem, fmt} ;
84
82
85
- use { httparse, traitobject} ;
86
- use typeable:: Typeable ;
83
+ use httparse;
87
84
use unicase:: UniCase ;
88
85
89
86
use self :: internals:: { Item , VecMap , Entry } ;
@@ -108,7 +105,7 @@ pub mod parsing;
108
105
///
109
106
/// This trait represents the construction and identification of headers,
110
107
/// and contains trait-object unsafe methods.
111
- pub trait Header : HeaderClone + Any + Typeable + Send + Sync {
108
+ pub trait Header : HeaderClone + Any + GetType + Send + Sync {
112
109
/// Returns the name of the header field this belongs to.
113
110
///
114
111
/// This will become an associated constant once available.
@@ -128,6 +125,33 @@ pub trait Header: HeaderClone + Any + Typeable + Send + Sync {
128
125
fn fmt_header ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result ;
129
126
}
130
127
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
+
131
155
#[ doc( hidden) ]
132
156
pub trait HeaderClone {
133
157
fn clone_box ( & self ) -> Box < Header + Send + Sync > ;
@@ -141,14 +165,22 @@ impl<T: Header + Clone> HeaderClone for T {
141
165
}
142
166
143
167
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.
144
176
#[ inline]
145
177
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 )
147
179
}
148
180
149
181
#[ inline]
150
182
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 )
152
184
}
153
185
}
154
186
0 commit comments