@@ -7,6 +7,7 @@ use nom::{
77 sequence:: { delimited, preceded, tuple} ,
88 IResult ,
99} ;
10+ use std:: borrow:: Cow ;
1011
1112use crate :: {
1213 parser:: { core:: * , rfc3501:: envelope} ,
@@ -35,8 +36,8 @@ fn body_fields(i: &[u8]) -> IResult<&[u8], BodyFields> {
3536 i,
3637 BodyFields {
3738 param,
38- id,
39- description,
39+ id : id . map ( Cow :: Borrowed ) ,
40+ description : description . map ( Cow :: Borrowed ) ,
4041 transfer_encoding,
4142 octets,
4243 } ,
@@ -60,10 +61,10 @@ fn body_ext_1part(i: &[u8]) -> IResult<&[u8], BodyExt1Part> {
6061 Ok ( (
6162 i,
6263 BodyExt1Part {
63- md5,
64+ md5 : md5 . map ( Cow :: Borrowed ) ,
6465 disposition,
6566 language,
66- location,
67+ location : location . map ( Cow :: Borrowed ) ,
6768 extension,
6869 } ,
6970 ) )
@@ -88,7 +89,7 @@ fn body_ext_mpart(i: &[u8]) -> IResult<&[u8], BodyExtMPart> {
8889 param,
8990 disposition,
9091 language,
91- location,
92+ location : location . map ( Cow :: Borrowed ) ,
9293 extension,
9394 } ,
9495 ) )
@@ -109,15 +110,20 @@ fn body_encoding(i: &[u8]) -> IResult<&[u8], ContentEncoding> {
109110 ) ) ,
110111 char ( '"' ) ,
111112 ) ,
112- map ( string_utf8, |enc| ContentEncoding :: Other ( enc) ) ,
113+ map ( string_utf8, |enc| {
114+ ContentEncoding :: Other ( Cow :: Borrowed ( enc) )
115+ } ) ,
113116 ) ) ( i)
114117}
115118
116- fn body_lang ( i : & [ u8 ] ) -> IResult < & [ u8 ] , Option < Vec < & str > > > {
119+ fn body_lang ( i : & [ u8 ] ) -> IResult < & [ u8 ] , Option < Vec < Cow < ' _ , str > > > > {
117120 alt ( (
118121 // body language seems to refer to RFC 3066 language tags, which should be ASCII-only
119- map ( nstring_utf8, |v| v. map ( |s| vec ! [ s] ) ) ,
120- map ( parenthesized_nonempty_list ( string_utf8) , Option :: from) ,
122+ map ( nstring_utf8, |v| v. map ( |s| vec ! [ Cow :: Borrowed ( s) ] ) ) ,
123+ map (
124+ parenthesized_nonempty_list ( map ( string_utf8, Cow :: Borrowed ) ) ,
125+ Option :: from,
126+ ) ,
121127 ) ) ( i)
122128}
123129
@@ -127,7 +133,7 @@ fn body_param(i: &[u8]) -> IResult<&[u8], BodyParams> {
127133 map (
128134 parenthesized_nonempty_list ( map (
129135 tuple ( ( string_utf8, tag ( " " ) , string_utf8) ) ,
130- |( key, _, val) | ( key, val) ,
136+ |( key, _, val) | ( Cow :: Borrowed ( key) , Cow :: Borrowed ( val) ) ,
131137 ) ) ,
132138 Option :: from,
133139 ) ,
@@ -139,7 +145,7 @@ fn body_extension(i: &[u8]) -> IResult<&[u8], BodyExtension> {
139145 map ( number, BodyExtension :: Num ) ,
140146 // Cannot find documentation on character encoding for body extension values.
141147 // So far, assuming UTF-8 seems fine, please report if you run into issues here.
142- map ( nstring_utf8, BodyExtension :: Str ) ,
148+ map ( nstring_utf8, |v| BodyExtension :: Str ( v . map ( Cow :: Borrowed ) ) ) ,
143149 map (
144150 parenthesized_nonempty_list ( body_extension) ,
145151 BodyExtension :: List ,
@@ -152,7 +158,12 @@ fn body_disposition(i: &[u8]) -> IResult<&[u8], Option<ContentDisposition>> {
152158 map ( nil, |_| None ) ,
153159 paren_delimited ( map (
154160 tuple ( ( string_utf8, tag ( " " ) , body_param) ) ,
155- |( ty, _, params) | Some ( ContentDisposition { ty, params } ) ,
161+ |( ty, _, params) | {
162+ Some ( ContentDisposition {
163+ ty : Cow :: Borrowed ( ty) ,
164+ params,
165+ } )
166+ } ,
156167 ) ) ,
157168 ) ) ( i)
158169}
@@ -170,8 +181,8 @@ fn body_type_basic(i: &[u8]) -> IResult<&[u8], BodyStructure> {
170181 |( ty, _, subtype, _, fields, ext) | BodyStructure :: Basic {
171182 common : BodyContentCommon {
172183 ty : ContentType {
173- ty,
174- subtype,
184+ ty : Cow :: Borrowed ( ty ) ,
185+ subtype : Cow :: Borrowed ( subtype ) ,
175186 params : fields. param ,
176187 } ,
177188 disposition : ext. disposition ,
@@ -205,8 +216,8 @@ fn body_type_text(i: &[u8]) -> IResult<&[u8], BodyStructure> {
205216 |( _, _, subtype, _, fields, _, lines, ext) | BodyStructure :: Text {
206217 common : BodyContentCommon {
207218 ty : ContentType {
208- ty : "TEXT" ,
209- subtype,
219+ ty : Cow :: Borrowed ( "TEXT" ) ,
220+ subtype : Cow :: Borrowed ( subtype ) ,
210221 params : fields. param ,
211222 } ,
212223 disposition : ext. disposition ,
@@ -243,8 +254,8 @@ fn body_type_message(i: &[u8]) -> IResult<&[u8], BodyStructure> {
243254 |( _, _, fields, _, envelope, _, body, _, lines, ext) | BodyStructure :: Message {
244255 common : BodyContentCommon {
245256 ty : ContentType {
246- ty : "MESSAGE" ,
247- subtype : "RFC822" ,
257+ ty : Cow :: Borrowed ( "MESSAGE" ) ,
258+ subtype : Cow :: Borrowed ( "RFC822" ) ,
248259 params : fields. param ,
249260 } ,
250261 disposition : ext. disposition ,
@@ -272,8 +283,8 @@ fn body_type_multipart(i: &[u8]) -> IResult<&[u8], BodyStructure> {
272283 |( bodies, _, subtype, ext) | BodyStructure :: Multipart {
273284 common : BodyContentCommon {
274285 ty : ContentType {
275- ty : "MULTIPART" ,
276- subtype,
286+ ty : Cow :: Borrowed ( "MULTIPART" ) ,
287+ subtype : Cow :: Borrowed ( subtype ) ,
277288 params : ext. param ,
278289 } ,
279290 disposition : ext. disposition ,
@@ -310,9 +321,10 @@ mod tests {
310321
311322 // body-fld-param SP body-fld-id SP body-fld-desc SP body-fld-enc SP body-fld-octets
312323 const BODY_FIELDS : & str = r#"("foo" "bar") "id" "desc" "7BIT" 1337"# ;
313- const BODY_FIELD_PARAM_PAIR : ( & str , & str ) = ( "foo" , "bar" ) ;
314- const BODY_FIELD_ID : Option < & str > = Some ( "id" ) ;
315- const BODY_FIELD_DESC : Option < & str > = Some ( "desc" ) ;
324+ const BODY_FIELD_PARAM_PAIR : ( Cow < ' _ , str > , Cow < ' _ , str > ) =
325+ ( Cow :: Borrowed ( "foo" ) , Cow :: Borrowed ( "bar" ) ) ;
326+ const BODY_FIELD_ID : Option < Cow < ' _ , str > > = Some ( Cow :: Borrowed ( "id" ) ) ;
327+ const BODY_FIELD_DESC : Option < Cow < ' _ , str > > = Some ( Cow :: Borrowed ( "desc" ) ) ;
316328 const BODY_FIELD_ENC : ContentEncoding = ContentEncoding :: SevenBit ;
317329 const BODY_FIELD_OCTETS : u32 = 1337 ;
318330
@@ -322,8 +334,8 @@ mod tests {
322334 BodyStructure :: Text {
323335 common : BodyContentCommon {
324336 ty : ContentType {
325- ty : "TEXT" ,
326- subtype : "PLAIN" ,
337+ ty : Cow :: Borrowed ( "TEXT" ) ,
338+ subtype : Cow :: Borrowed ( "PLAIN" ) ,
327339 params : Some ( vec ! [ BODY_FIELD_PARAM_PAIR ] ) ,
328340 } ,
329341 disposition : None ,
@@ -350,7 +362,7 @@ mod tests {
350362 assert_matches ! (
351363 body_param( br#"("foo" "bar")"# ) ,
352364 Ok ( ( EMPTY , Some ( param) ) ) => {
353- assert_eq!( param, vec![ ( "foo" , "bar" ) ] ) ;
365+ assert_eq!( param, vec![ ( Cow :: Borrowed ( "foo" ) , Cow :: Borrowed ( "bar" ) ) ] ) ;
354366 }
355367 ) ;
356368 }
@@ -378,7 +390,7 @@ mod tests {
378390 fn test_body_extension_data ( ) {
379391 assert_matches ! (
380392 body_extension( br#""blah""# ) ,
381- Ok ( ( EMPTY , BodyExtension :: Str ( Some ( "blah" ) ) ) )
393+ Ok ( ( EMPTY , BodyExtension :: Str ( Some ( Cow :: Borrowed ( "blah" ) ) ) ) )
382394 ) ;
383395
384396 assert_matches ! (
@@ -389,7 +401,7 @@ mod tests {
389401 assert_matches ! (
390402 body_extension( br#"("hello")"# ) ,
391403 Ok ( ( EMPTY , BodyExtension :: List ( list) ) ) => {
392- assert_eq!( list, vec![ BodyExtension :: Str ( Some ( "hello" ) ) ] ) ;
404+ assert_eq!( list, vec![ BodyExtension :: Str ( Some ( Cow :: Borrowed ( "hello" ) ) ) ] ) ;
393405 }
394406 ) ;
395407
@@ -409,9 +421,9 @@ mod tests {
409421 body_disposition( br#"("attachment" ("FILENAME" "pages.pdf"))"# ) ,
410422 Ok ( ( EMPTY , Some ( disposition) ) ) => {
411423 assert_eq!( disposition, ContentDisposition {
412- ty: "attachment" ,
424+ ty: Cow :: Borrowed ( "attachment" ) ,
413425 params: Some ( vec![
414- ( "FILENAME" , "pages.pdf" )
426+ ( Cow :: Borrowed ( "FILENAME" ) , Cow :: Borrowed ( "pages.pdf" ) )
415427 ] )
416428 } ) ;
417429 }
@@ -453,13 +465,13 @@ mod tests {
453465 assert_eq!( basic, BodyStructure :: Basic {
454466 common: BodyContentCommon {
455467 ty: ContentType {
456- ty: "APPLICATION" ,
457- subtype: "PDF" ,
458- params: Some ( vec![ ( "NAME" , "pages.pdf" ) ] )
468+ ty: Cow :: Borrowed ( "APPLICATION" ) ,
469+ subtype: Cow :: Borrowed ( "PDF" ) ,
470+ params: Some ( vec![ ( Cow :: Borrowed ( "NAME" ) , Cow :: Borrowed ( "pages.pdf" ) ) ] )
459471 } ,
460472 disposition: Some ( ContentDisposition {
461- ty: "attachment" ,
462- params: Some ( vec![ ( "FILENAME" , "pages.pdf" ) ] )
473+ ty: Cow :: Borrowed ( "attachment" ) ,
474+ params: Some ( vec![ ( Cow :: Borrowed ( "FILENAME" ) , Cow :: Borrowed ( "pages.pdf" ) ) ] )
463475 } ) ,
464476 language: None ,
465477 location: None ,
@@ -507,8 +519,8 @@ mod tests {
507519 assert_eq!( multipart, BodyStructure :: Multipart {
508520 common: BodyContentCommon {
509521 ty: ContentType {
510- ty: "MULTIPART" ,
511- subtype: "ALTERNATIVE" ,
522+ ty: Cow :: Borrowed ( "MULTIPART" ) ,
523+ subtype: Cow :: Borrowed ( "ALTERNATIVE" ) ,
512524 params: None
513525 } ,
514526 language: None ,
0 commit comments