@@ -2,6 +2,7 @@ use crate::de::str2bool;
22use crate :: encoding:: Decoder ;
33use crate :: errors:: serialize:: DeError ;
44use crate :: name:: QName ;
5+ use crate :: utils:: CowRef ;
56use serde:: de:: { DeserializeSeed , Deserializer , EnumAccess , VariantAccess , Visitor } ;
67use serde:: { forward_to_deserialize_any, serde_if_integer128} ;
78use std:: borrow:: Cow ;
@@ -60,18 +61,19 @@ fn decode_name<'n>(name: QName<'n>, decoder: Decoder) -> Result<Cow<'n, str>, De
6061///
6162/// `deserialize_any()` returns the same result as `deserialize_identifier()`.
6263///
63- /// # Lifetime
64+ /// # Lifetimes
6465///
66+ /// - `'i`: lifetime of the data that the deserializer borrows from the parsed input
6567/// - `'d`: lifetime of a deserializer that holds a buffer with content of events
6668///
6769/// [`attribute`]: Self::from_attr
6870/// [`local_name()`]: QName::local_name
6971/// [`Deserialize`]: serde::Deserialize
70- pub struct QNameDeserializer < ' d > {
71- name : Cow < ' d , str > ,
72+ pub struct QNameDeserializer < ' i , ' d > {
73+ name : CowRef < ' i , ' d , str > ,
7274}
7375
74- impl < ' d > QNameDeserializer < ' d > {
76+ impl < ' i , ' d > QNameDeserializer < ' i , ' d > {
7577 /// Creates deserializer from name of an attribute
7678 pub fn from_attr ( name : QName < ' d > , decoder : Decoder ) -> Result < Self , DeError > {
7779 // https://github.com/tafia/quick-xml/issues/537
@@ -83,19 +85,34 @@ impl<'d> QNameDeserializer<'d> {
8385 } ;
8486
8587 Ok ( Self {
86- name : Cow :: Owned ( format ! ( "@{field}" ) ) ,
88+ name : CowRef :: Owned ( format ! ( "@{field}" ) ) ,
8789 } )
8890 }
8991
9092 /// Creates deserializer from name of an element
91- pub fn from_elem ( name : QName < ' d > , decoder : Decoder ) -> Result < Self , DeError > {
92- let local = decode_name ( name, decoder) ?;
93+ pub fn from_elem ( name : CowRef < ' i , ' d , [ u8 ] > , decoder : Decoder ) -> Result < Self , DeError > {
94+ let local = match name {
95+ CowRef :: Input ( borrowed) => match decode_name ( QName ( borrowed) , decoder) ? {
96+ Cow :: Borrowed ( borrowed) => CowRef :: Input ( borrowed) ,
97+ Cow :: Owned ( owned) => CowRef :: Owned ( owned) ,
98+ } ,
99+ CowRef :: Slice ( borrowed) => match decode_name ( QName ( borrowed) , decoder) ? {
100+ Cow :: Borrowed ( borrowed) => CowRef :: Slice ( borrowed) ,
101+ Cow :: Owned ( owned) => CowRef :: Owned ( owned) ,
102+ } ,
103+ CowRef :: Owned ( owned) => match decode_name ( QName ( & owned) , decoder) ? {
104+ // SAFETY: Because result is borrowed, no changes was done
105+ // and we can safely unwrap here
106+ Cow :: Borrowed ( _) => CowRef :: Owned ( String :: from_utf8 ( owned) . unwrap ( ) ) ,
107+ Cow :: Owned ( owned) => CowRef :: Owned ( owned) ,
108+ } ,
109+ } ;
93110
94111 Ok ( Self { name : local } )
95112 }
96113}
97114
98- impl < ' de , ' d > Deserializer < ' de > for QNameDeserializer < ' d > {
115+ impl < ' de , ' d > Deserializer < ' de > for QNameDeserializer < ' de , ' d > {
99116 type Error = DeError ;
100117
101118 forward_to_deserialize_any ! {
@@ -202,8 +219,9 @@ impl<'de, 'd> Deserializer<'de> for QNameDeserializer<'d> {
202219 V : Visitor < ' de > ,
203220 {
204221 match self . name {
205- Cow :: Borrowed ( name) => visitor. visit_str ( name) ,
206- Cow :: Owned ( name) => visitor. visit_string ( name) ,
222+ CowRef :: Input ( name) => visitor. visit_borrowed_str ( name) ,
223+ CowRef :: Slice ( name) => visitor. visit_str ( name) ,
224+ CowRef :: Owned ( name) => visitor. visit_string ( name) ,
207225 }
208226 }
209227
@@ -220,7 +238,7 @@ impl<'de, 'd> Deserializer<'de> for QNameDeserializer<'d> {
220238 }
221239}
222240
223- impl < ' de , ' d > EnumAccess < ' de > for QNameDeserializer < ' d > {
241+ impl < ' de , ' d > EnumAccess < ' de > for QNameDeserializer < ' de , ' d > {
224242 type Error = DeError ;
225243 type Variant = QNameUnitOnly ;
226244
@@ -337,7 +355,7 @@ mod tests {
337355 #[ test]
338356 fn $name( ) {
339357 let de = QNameDeserializer {
340- name: Cow :: Borrowed ( $input) ,
358+ name: CowRef :: Input ( $input) ,
341359 } ;
342360 let data: $type = Deserialize :: deserialize( de) . unwrap( ) ;
343361
@@ -352,7 +370,7 @@ mod tests {
352370 #[ test]
353371 fn $name( ) {
354372 let de = QNameDeserializer {
355- name: Cow :: Borrowed ( $input) ,
373+ name: CowRef :: Input ( $input) ,
356374 } ;
357375 let data: $type = Deserialize :: deserialize( de) . unwrap( ) ;
358376
@@ -377,7 +395,7 @@ mod tests {
377395 #[ test]
378396 fn $name( ) {
379397 let de = QNameDeserializer {
380- name: Cow :: Borrowed ( $input) ,
398+ name: CowRef :: Input ( $input) ,
381399 } ;
382400 let err = <$type as Deserialize >:: deserialize( de) . unwrap_err( ) ;
383401
@@ -420,8 +438,7 @@ mod tests {
420438 => Custom ( "invalid value: string \" <\" , expected a character" ) ) ;
421439
422440 deserialized_to ! ( string: String = "<escaped string" => "<escaped string" ) ;
423- err ! ( borrowed_str: & str = "name"
424- => Custom ( "invalid type: string \" name\" , expected a borrowed string" ) ) ;
441+ deserialized_to ! ( borrowed_str: & str = "name" => "name" ) ;
425442
426443 err ! ( byte_buf: ByteBuf = "<escaped string"
427444 => Custom ( "invalid type: string \" <escaped string\" , expected byte data" ) ) ;
0 commit comments