@@ -14,6 +14,7 @@ pub const STD_HASH_STATE: &str = ", std::collections::hash::map::RandomState>";
14
14
pub const CORE_REF_CELL : & str = "core::cell::RefCell<" ;
15
15
pub const STD_MUTEX : & str = "std::sync::mutex::Mutex<" ;
16
16
pub const STD_RWLOCK : & str = "std::sync::rwlock::RwLock<" ;
17
+ pub const STD_OS_STRING : & str = "std::ffi::os_str::OsString" ;
17
18
18
19
#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
19
20
#[ serde( tag = "type" ) ]
@@ -297,15 +298,7 @@ impl Display for RValue {
297
298
if typename. starts_with ( '&' ) {
298
299
write ! ( f, "&" ) ?;
299
300
}
300
- write ! ( f, "[" ) ?;
301
- for ( i, b) in value. iter ( ) . enumerate ( ) {
302
- write ! (
303
- f,
304
- "0x{b:02x}{}" ,
305
- if i < value. len( ) - 1 { ", " } else { "" }
306
- ) ?;
307
- }
308
- write ! ( f, "]" ) ?;
301
+ print_bytes ( f, & value) ?;
309
302
}
310
303
Self :: Ref {
311
304
typename, value, ..
@@ -409,7 +402,9 @@ impl Display for RValue {
409
402
}
410
403
return write ! ( f, ")" ) ;
411
404
}
412
- if ( typename. starts_with ( STD_HASH_MAP ) || typename. starts_with ( STD_HASH_SET ) )
405
+ if typename == STD_OS_STRING {
406
+ print_os_string ( f, fields, width, pretty) ?;
407
+ } else if ( typename. starts_with ( STD_HASH_MAP ) || typename. starts_with ( STD_HASH_SET ) )
413
408
&& typename. ends_with ( STD_HASH_STATE )
414
409
&& ( fields. contains_key ( "items" ) && fields. contains_key ( "len" ) )
415
410
{
@@ -652,6 +647,53 @@ fn print_hashmap(
652
647
Ok ( ( ) )
653
648
}
654
649
650
+ fn print_os_string (
651
+ f : & mut std:: fmt:: Formatter < ' _ > ,
652
+ fields : & IndexMap < String , RValue > ,
653
+ width : usize ,
654
+ pretty : bool ,
655
+ ) -> std:: fmt:: Result {
656
+ write ! ( f, "{}::from_encoded_bytes_unchecked(" , STD_OS_STRING ) ?;
657
+ if pretty {
658
+ write ! (
659
+ f,
660
+ "{}" ,
661
+ String :: from_utf8( vec![ b' ' ; ( width + 1 ) * 4 ] ) . unwrap( )
662
+ ) ?;
663
+ }
664
+ let inner = match fields. get ( "inner" ) {
665
+ Some ( RValue :: Struct { fields, .. } ) => {
666
+ if let Some ( inner) = fields. get ( "inner" ) {
667
+ match inner {
668
+ RValue :: Bytes { value, .. } => value,
669
+ _ => {
670
+ write ! ( f, "?)" ) ?;
671
+ return Ok ( ( ) ) ;
672
+ }
673
+ }
674
+ } else {
675
+ write ! ( f, "?)" ) ?;
676
+ return Ok ( ( ) ) ;
677
+ }
678
+ }
679
+ _ => {
680
+ write ! ( f, "?)" ) ?;
681
+ return Ok ( ( ) ) ;
682
+ }
683
+ } ;
684
+ if let Ok ( string) = std:: str:: from_utf8 ( inner) {
685
+ write ! ( f, "String::from({:?}).into_bytes()" , string) ?;
686
+ } else {
687
+ write ! ( f, "vec!" ) ?;
688
+ print_bytes ( f, inner) ?;
689
+ }
690
+ if pretty {
691
+ write ! ( f, "{}" , String :: from_utf8( vec![ b' ' ; width * 4 ] ) . unwrap( ) ) ?;
692
+ }
693
+ write ! ( f, ")" ) ?;
694
+ Ok ( ( ) )
695
+ }
696
+
655
697
fn print_arr_items (
656
698
f : & mut std:: fmt:: Formatter < ' _ > ,
657
699
data : & [ RValue ] ,
@@ -683,6 +725,19 @@ fn print_arr_items(
683
725
Ok ( ( ) )
684
726
}
685
727
728
+ fn print_bytes ( f : & mut std:: fmt:: Formatter < ' _ > , bytes : & [ u8 ] ) -> std:: fmt:: Result {
729
+ write ! ( f, "[" ) ?;
730
+ for ( i, b) in bytes. iter ( ) . enumerate ( ) {
731
+ write ! (
732
+ f,
733
+ "0x{b:02x}{}" ,
734
+ if i < bytes. len( ) - 1 { ", " } else { "" }
735
+ ) ?;
736
+ }
737
+ write ! ( f, "]" ) ?;
738
+ Ok ( ( ) )
739
+ }
740
+
686
741
impl RValue {
687
742
pub fn typename ( & self ) -> String {
688
743
match self {
0 commit comments