@@ -261,7 +261,10 @@ impl From<&str> for Content {
261261
262262#[ cfg( test) ]
263263mod tests {
264+ use std:: { fmt:: Display , str:: FromStr } ;
265+
264266 use super :: * ;
267+ use facet:: Facet ;
265268 use facet_testhelpers:: test;
266269
267270 #[ test]
@@ -556,4 +559,82 @@ mod tests {
556559
557560 assert ! ( result. elements. is_empty( ) ) ;
558561 }
562+
563+ #[ derive( Debug , Facet ) ]
564+ #[ facet( proxy = StringRepr ) ]
565+ struct ConstantName ;
566+
567+ /// A proxy type for Facet that uses the Display/FromStr implementation
568+ #[ derive( Debug , Facet ) ]
569+ #[ repr( transparent) ]
570+ pub ( crate ) struct StringRepr ( pub String ) ;
571+
572+ impl Display for ConstantName {
573+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
574+ write ! ( f, "CONSTANT" )
575+ }
576+ }
577+
578+ impl FromStr for ConstantName {
579+ type Err = & ' static str ;
580+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
581+ if s == "CONSTANT" {
582+ Ok ( Self )
583+ } else {
584+ Err ( "expected `CONSTANT`" )
585+ }
586+ }
587+ }
588+
589+ impl From < ConstantName > for StringRepr {
590+ fn from ( value : ConstantName ) -> Self {
591+ Self ( value. to_string ( ) )
592+ }
593+ }
594+ impl From < & ConstantName > for StringRepr {
595+ fn from ( value : & ConstantName ) -> Self {
596+ Self ( value. to_string ( ) )
597+ }
598+ }
599+ impl TryFrom < StringRepr > for ConstantName {
600+ type Error = <ConstantName as core:: str:: FromStr >:: Err ;
601+ fn try_from ( value : StringRepr ) -> Result < Self , Self :: Error > {
602+ value. 0 . parse ( )
603+ }
604+ }
605+ impl TryFrom < & StringRepr > for ConstantName {
606+ type Error = <ConstantName as core:: str:: FromStr >:: Err ;
607+ fn try_from ( value : & StringRepr ) -> Result < Self , Self :: Error > {
608+ value. 0 . parse ( )
609+ }
610+ }
611+
612+ #[ derive( Debug , Facet ) ]
613+ #[ repr( C ) ]
614+ enum Foo {
615+ #[ facet( rename = "foo" ) ]
616+ Value {
617+ #[ facet( xml:: attribute) ]
618+ #[ allow( unused) ]
619+ name : ConstantName ,
620+ #[ facet( xml:: attribute) ]
621+ #[ allow( unused) ]
622+ exists : String ,
623+ } ,
624+ }
625+
626+ #[ test]
627+ fn transparent_attribute_not_discarded ( ) {
628+ let raw_xml = r#"
629+ <foo name="CONSTANT" exists="i do exist and am not discarded"></foo>"# ;
630+ let x: Foo = facet_xml:: from_str ( raw_xml) . unwrap ( ) ;
631+ let element = crate :: to_element ( & x) . unwrap ( ) ;
632+ let _ = facet_xml:: to_string ( & x) . unwrap ( ) ;
633+ let _ = facet_xml:: to_string ( & element) . unwrap ( ) ;
634+ assert ! (
635+ element. attrs. contains_key( "exists" ) ,
636+ "this attribute is not discarded"
637+ ) ;
638+ assert_eq ! ( element. attrs[ "name" ] , "CONSTANT" , "name is not discarded" ) ;
639+ }
559640}
0 commit comments