@@ -28,15 +28,15 @@ use infer::Infer;
2828/// ```
2929// NOTE: we cannot statically initialize Strings with values yet, so we keep dedicated static
3030// fields for the static strings.
31- #[ derive( Clone ) ]
31+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
3232pub struct Mime {
33- pub ( crate ) essence : String ,
34- pub ( crate ) basetype : String ,
35- pub ( crate ) subtype : String ,
36- pub ( crate ) static_essence : Option < & ' static str > ,
37- pub ( crate ) static_basetype : Option < & ' static str > ,
38- pub ( crate ) static_subtype : Option < & ' static str > ,
39- pub ( crate ) params : Option < ParamKind > ,
33+ pub ( crate ) essence : Cow < ' static , str > ,
34+ pub ( crate ) basetype : Cow < ' static , str > ,
35+ pub ( crate ) subtype : Cow < ' static , str > ,
36+ // NOTE(yosh): this is a hack because we can't populate vecs in const yet.
37+ // This enables us to encode media types as utf-8 at compilation.
38+ pub ( crate ) is_utf8 : bool ,
39+ pub ( crate ) params : Vec < ( ParamName , ParamValue ) > ,
4040}
4141
4242impl Mime {
@@ -68,87 +68,40 @@ impl Mime {
6868 /// According to the spec this method should be named `type`, but that's a reserved keyword in
6969 /// Rust so hence prefix with `base` instead.
7070 pub fn basetype ( & self ) -> & str {
71- if let Some ( basetype) = self . static_basetype {
72- & basetype
73- } else {
74- & self . basetype
75- }
71+ & self . basetype
7672 }
7773
7874 /// Access the Mime's `subtype` value.
7975 pub fn subtype ( & self ) -> & str {
80- if let Some ( subtype) = self . static_subtype {
81- & subtype
82- } else {
83- & self . subtype
84- }
76+ & self . subtype
8577 }
8678
8779 /// Access the Mime's `essence` value.
8880 pub fn essence ( & self ) -> & str {
89- if let Some ( essence) = self . static_essence {
90- & essence
91- } else {
92- & self . essence
93- }
81+ & self . essence
9482 }
9583
9684 /// Get a reference to a param.
9785 pub fn param ( & self , name : impl Into < ParamName > ) -> Option < & ParamValue > {
9886 let name: ParamName = name. into ( ) ;
99- self . params
100- . as_ref ( )
101- . map ( |inner| match inner {
102- ParamKind :: Vec ( v) => v
103- . iter ( )
104- . find_map ( |( k, v) | if k == & name { Some ( v) } else { None } ) ,
105- ParamKind :: Utf8 => match name {
106- ParamName ( Cow :: Borrowed ( "charset" ) ) => Some ( & ParamValue ( Cow :: Borrowed ( "utf8" ) ) ) ,
107- _ => None ,
108- } ,
109- } )
110- . flatten ( )
87+ if name. as_str ( ) == "charset" && self . is_utf8 {
88+ return Some ( & ParamValue ( Cow :: Borrowed ( "utf-8" ) ) ) ;
89+ }
90+
91+ self . params . iter ( ) . find ( |( k, _) | k == & name) . map ( |( _, v) | v)
11192 }
11293
11394 /// Remove a param from the set. Returns the `ParamValue` if it was contained within the set.
11495 pub fn remove_param ( & mut self , name : impl Into < ParamName > ) -> Option < ParamValue > {
11596 let name: ParamName = name. into ( ) ;
116- let mut unset_params = false ;
117- let ret = self
118- . params
119- . as_mut ( )
120- . map ( |inner| match inner {
121- ParamKind :: Vec ( v) => match v. iter ( ) . position ( |( k, _) | k == & name) {
122- Some ( index) => Some ( v. remove ( index) . 1 ) ,
123- None => None ,
124- } ,
125- ParamKind :: Utf8 => match name {
126- ParamName ( Cow :: Borrowed ( "charset" ) ) => {
127- unset_params = true ;
128- Some ( ParamValue ( Cow :: Borrowed ( "utf8" ) ) )
129- }
130- _ => None ,
131- } ,
132- } )
133- . flatten ( ) ;
134- if unset_params {
135- self . params = None ;
97+ if name. as_str ( ) == "charset" && self . is_utf8 {
98+ self . is_utf8 = false ;
99+ return Some ( ParamValue ( Cow :: Borrowed ( "utf-8" ) ) ) ;
136100 }
137- ret
138- }
139- }
140-
141- impl PartialEq < Mime > for Mime {
142- fn eq ( & self , other : & Mime ) -> bool {
143- let left = match self . static_essence {
144- Some ( essence) => essence,
145- None => & self . essence ,
146- } ;
147- let right = match other. static_essence {
148- Some ( essence) => essence,
149- None => & other. essence ,
150- } ;
151- left == right
101+ self . params
102+ . iter ( )
103+ . position ( |( k, _) | k == & name)
104+ . map ( |pos| self . params . remove ( pos) . 1 )
152105 }
153106}
154107
@@ -158,15 +111,11 @@ impl Display for Mime {
158111 }
159112}
160113
161- impl Debug for Mime {
162- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
163- if let Some ( essence) = self . static_essence {
164- Debug :: fmt ( essence, f)
165- } else {
166- Debug :: fmt ( & self . essence , f)
167- }
168- }
169- }
114+ // impl Debug for Mime {
115+ // fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116+ // Debug::fmt(&self.essence, f)
117+ // }
118+ // }
170119
171120impl FromStr for Mime {
172121 type Err = crate :: Error ;
@@ -196,6 +145,7 @@ impl ToHeaderValues for Mime {
196145 Ok ( header. to_header_values ( ) . unwrap ( ) )
197146 }
198147}
148+
199149/// A parameter name.
200150#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
201151pub struct ParamName ( Cow < ' static , str > ) ;
@@ -259,11 +209,3 @@ impl PartialEq<str> for ParamValue {
259209 self . 0 == other
260210 }
261211}
262-
263- /// This is a hack that allows us to mark a trait as utf8 during compilation. We
264- /// can remove this once we can construct HashMap during compilation.
265- #[ derive( Debug , Clone , PartialEq , Eq ) ]
266- pub ( crate ) enum ParamKind {
267- Utf8 ,
268- Vec ( Vec < ( ParamName , ParamValue ) > ) ,
269- }
0 commit comments