@@ -21,7 +21,7 @@ use crate::{serialize_scalar, Key, KeyType, ScalarError};
21
21
/// Settings -> DockerSettings -> bridge_ip = u64
22
22
/// would turn into a key of "settings.docker-settings.bridge-ip" and a serialized String
23
23
/// representing the u64 data.
24
- pub fn to_pairs < T : Serialize > ( value : & T ) -> Result < HashMap < Key , String > > {
24
+ pub fn to_pairs ( value : & serde_json :: Value ) -> Result < HashMap < Key , String > > {
25
25
let mut output = HashMap :: new ( ) ;
26
26
let serializer = Serializer :: new ( & mut output, None ) ;
27
27
value. serialize ( serializer) ?;
@@ -30,10 +30,9 @@ pub fn to_pairs<T: Serialize>(value: &T) -> Result<HashMap<Key, String>> {
30
30
31
31
/// Like to_pairs, but lets you add an arbitrary prefix to the resulting keys. A separator will
32
32
/// automatically be added after the prefix.
33
- pub fn to_pairs_with_prefix < S , T > ( prefix : S , value : & T ) -> Result < HashMap < Key , String > >
33
+ pub fn to_pairs_with_prefix < S > ( prefix : S , value : & serde_json :: Value ) -> Result < HashMap < Key , String > >
34
34
where
35
35
S : AsRef < str > ,
36
- T : Serialize ,
37
36
{
38
37
let prefix = prefix. as_ref ( ) ;
39
38
let prefix_key = Key :: new ( KeyType :: Data , prefix) . map_err ( |e| {
@@ -230,9 +229,12 @@ impl<'a> ser::Serializer for Serializer<'a> {
230
229
bad_type ( "bytes" )
231
230
}
232
231
233
- // We just don't expect to need these, and we doesn't have a great way to represent them.
232
+ // serde_json::Value::Null is the only case where we should see this, so we can essentially
233
+ // consider this to be serialize_null(). Since we should only see null values in a settings
234
+ // input when the settings structure has an Option<T>, it should be safe to omit the key/value
235
+ // pair from the serialization output if the value is null.
234
236
fn serialize_unit ( self ) -> Result < ( ) > {
235
- bad_type ( "unit" )
237
+ Ok ( ( ) )
236
238
}
237
239
238
240
fn serialize_unit_struct ( self , _name : & ' static str ) -> Result < ( ) > {
@@ -490,6 +492,7 @@ mod test {
490
492
use crate :: { Key , KeyType } ;
491
493
use maplit:: hashmap;
492
494
use serde:: Serialize ;
495
+ use serde_json:: json;
493
496
494
497
// Helper macro for making a data Key for testing whose name we know is valid.
495
498
macro_rules! key {
@@ -516,20 +519,22 @@ mod test {
516
519
list : vec ! [ 3 , 4 , 5 ] ,
517
520
boolean : true ,
518
521
} ;
519
- let keys = to_pairs ( & b) . unwrap ( ) ;
522
+ let j = serde_json:: to_value ( b) . unwrap ( ) ;
523
+ let keys = to_pairs ( & j) . unwrap ( ) ;
520
524
assert_eq ! (
521
525
keys,
522
526
hashmap!(
523
- key!( "B. list" ) => "[3,4,5]" . to_string( ) ,
524
- key!( "B. boolean" ) => "true" . to_string( ) ,
527
+ key!( "list" ) => "[3,4,5]" . to_string( ) ,
528
+ key!( "boolean" ) => "true" . to_string( ) ,
525
529
)
526
530
) ;
527
531
}
528
532
529
533
#[ test]
530
534
fn empty_value ( ) {
531
535
let val: toml:: Value = toml:: from_str ( "" ) . unwrap ( ) ;
532
- let keys = to_pairs ( & val) . unwrap ( ) ;
536
+ let json = serde_json:: to_value ( val) . unwrap ( ) ;
537
+ let keys = to_pairs ( & json) . unwrap ( ) ;
533
538
assert_eq ! ( keys, hashmap!( ) )
534
539
}
535
540
@@ -540,13 +545,14 @@ mod test {
540
545
boolean : true ,
541
546
} ;
542
547
let a = A { id : 42 , b : Some ( b) } ;
543
- let keys = to_pairs ( & a) . unwrap ( ) ;
548
+ let j = serde_json:: to_value ( a) . unwrap ( ) ;
549
+ let keys = to_pairs ( & j) . unwrap ( ) ;
544
550
assert_eq ! (
545
551
keys,
546
552
hashmap!(
547
- key!( "A. b.list" ) => "[5,6,7]" . to_string( ) ,
548
- key!( "A. b.boolean" ) => "true" . to_string( ) ,
549
- key!( "A. id" ) => "42" . to_string( ) ,
553
+ key!( "b.list" ) => "[5,6,7]" . to_string( ) ,
554
+ key!( "b.boolean" ) => "true" . to_string( ) ,
555
+ key!( "id" ) => "42" . to_string( ) ,
550
556
)
551
557
) ;
552
558
}
@@ -559,7 +565,8 @@ mod test {
559
565
key!( "ie" ) => 43 ,
560
566
) ,
561
567
) ;
562
- let keys = to_pairs_with_prefix ( "map" , & m) . unwrap ( ) ;
568
+ let j = serde_json:: to_value ( m) . unwrap ( ) ;
569
+ let keys = to_pairs_with_prefix ( "map" , & j) . unwrap ( ) ;
563
570
assert_eq ! (
564
571
keys,
565
572
hashmap!(
@@ -577,7 +584,8 @@ mod test {
577
584
key!( "ie" ) => 43 ,
578
585
) ,
579
586
) ;
580
- let keys = to_pairs ( & m) . unwrap ( ) ;
587
+ let j = serde_json:: to_value ( m) . unwrap ( ) ;
588
+ let keys = to_pairs ( & j) . unwrap ( ) ;
581
589
assert_eq ! (
582
590
keys,
583
591
hashmap!(
@@ -590,7 +598,8 @@ mod test {
590
598
#[ test]
591
599
fn concrete_fails ( ) {
592
600
let i = 42 ;
593
- to_pairs ( & i) . unwrap_err ( ) ;
601
+ let j = serde_json:: to_value ( i) . unwrap ( ) ;
602
+ to_pairs ( & j) . unwrap_err ( ) ;
594
603
}
595
604
596
605
#[ test]
@@ -601,7 +610,8 @@ mod test {
601
610
key!( "ie" ) => "oranges" ,
602
611
) ,
603
612
) ;
604
- let keys = to_pairs ( & m) . unwrap ( ) ;
613
+ let j = serde_json:: to_value ( m) . unwrap ( ) ;
614
+ let keys = to_pairs ( & j) . unwrap ( ) ;
605
615
assert_eq ! (
606
616
keys,
607
617
hashmap!(
@@ -626,7 +636,8 @@ mod test {
626
636
key!( "ie" ) => TestEnum :: Beta ,
627
637
) ,
628
638
) ;
629
- let keys = to_pairs ( & m) . unwrap ( ) ;
639
+ let j = serde_json:: to_value ( m) . unwrap ( ) ;
640
+ let keys = to_pairs ( & j) . unwrap ( ) ;
630
641
assert_eq ! (
631
642
keys,
632
643
hashmap!(
@@ -635,4 +646,131 @@ mod test {
635
646
)
636
647
) ;
637
648
}
649
+
650
+ #[ test]
651
+ fn json_null ( ) {
652
+ let j = json ! ( null) ;
653
+ let keys = to_pairs_with_prefix ( "null" , & j) . unwrap ( ) ;
654
+ // the null value and its key should be skipped in serialization, resulting in an empty
655
+ // hashmap
656
+ assert_eq ! ( keys, hashmap!( ) ) ;
657
+ }
658
+
659
+ #[ test]
660
+ fn json_bool ( ) {
661
+ let j = json ! ( true ) ;
662
+ let keys = to_pairs_with_prefix ( "bool" , & j) . unwrap ( ) ;
663
+ assert_eq ! (
664
+ keys,
665
+ hashmap!(
666
+ key!( "bool" ) => "true" . to_string( ) ,
667
+ )
668
+ ) ;
669
+ }
670
+
671
+ #[ test]
672
+ fn json_number ( ) {
673
+ let j = json ! ( 42 ) ;
674
+ let keys = to_pairs_with_prefix ( "number" , & j) . unwrap ( ) ;
675
+ assert_eq ! (
676
+ keys,
677
+ hashmap!(
678
+ key!( "number" ) => "42" . to_string( ) ,
679
+ )
680
+ ) ;
681
+ }
682
+
683
+ #[ test]
684
+ fn json_number_float ( ) {
685
+ let j = json ! ( 4.2 ) ;
686
+ let keys = to_pairs_with_prefix ( "number" , & j) . unwrap ( ) ;
687
+ assert_eq ! (
688
+ keys,
689
+ hashmap!(
690
+ key!( "number" ) => "4.2" . to_string( ) ,
691
+ )
692
+ ) ;
693
+ }
694
+
695
+ #[ test]
696
+ fn json_string ( ) {
697
+ let j = json ! ( "hello" ) ;
698
+ let keys = to_pairs_with_prefix ( "string" , & j) . unwrap ( ) ;
699
+ assert_eq ! (
700
+ keys,
701
+ hashmap!(
702
+ key!( "string" ) => "\" hello\" " . to_string( ) ,
703
+ )
704
+ ) ;
705
+ }
706
+
707
+ #[ test]
708
+ fn json_array ( ) {
709
+ let j = json ! ( [ "foo" , true , 42 ] ) ;
710
+ let keys = to_pairs_with_prefix ( "array" , & j) . unwrap ( ) ;
711
+ assert_eq ! (
712
+ keys,
713
+ hashmap!(
714
+ key!( "array" ) => "[\" foo\" ,true,42]" . to_string( ) ,
715
+ )
716
+ ) ;
717
+ }
718
+
719
+ #[ test]
720
+ fn json_array_with_null ( ) {
721
+ let j = json ! ( [ "foo" , null, true , 42 ] ) ;
722
+ let keys = to_pairs_with_prefix ( "array" , & j) . unwrap ( ) ;
723
+ assert_eq ! (
724
+ keys,
725
+ hashmap!(
726
+ key!( "array" ) => "[\" foo\" ,null,true,42]" . to_string( ) ,
727
+ )
728
+ ) ;
729
+ }
730
+
731
+ #[ test]
732
+ fn json_object ( ) {
733
+ let j = json ! ( {
734
+ "bool" : true ,
735
+ "number" : 42 ,
736
+ "string" : "foo" ,
737
+ "array" : [ "foo" , true , null, 42 ] ,
738
+ "object" : { "number" : 4.2 }
739
+ } ) ;
740
+ let keys = to_pairs_with_prefix ( "object" , & j) . unwrap ( ) ;
741
+ assert_eq ! (
742
+ keys,
743
+ hashmap!(
744
+ key!( "object.bool" ) => "true" . to_string( ) ,
745
+ key!( "object.number" ) => "42" . to_string( ) ,
746
+ key!( "object.string" ) => "\" foo\" " . to_string( ) ,
747
+ key!( "object.array" ) => "[\" foo\" ,true,null,42]" . to_string( ) ,
748
+ key!( "object.object.number" ) => "4.2" . to_string( ) ,
749
+ )
750
+ ) ;
751
+ }
752
+
753
+ #[ test]
754
+ fn json_object_with_null ( ) {
755
+ let j = json ! ( {
756
+ "null" : null,
757
+ "bool" : true ,
758
+ "number" : 42 ,
759
+ "string" : "foo" ,
760
+ "array" : [ "foo" , true , null, 42 ] ,
761
+ "object" : { "number" : 4.2 }
762
+ } ) ;
763
+ let keys = to_pairs_with_prefix ( "object" , & j) . unwrap ( ) ;
764
+ // the null value and its key should be skipped in serialization
765
+ assert_eq ! (
766
+ keys,
767
+ hashmap!(
768
+ key!( "object.bool" ) => "true" . to_string( ) ,
769
+ key!( "object.number" ) => "42" . to_string( ) ,
770
+ key!( "object.string" ) => "\" foo\" " . to_string( ) ,
771
+ key!( "object.array" ) => "[\" foo\" ,true,null,42]" . to_string( ) ,
772
+ key!( "object.object.number" ) => "4.2" . to_string( ) ,
773
+ )
774
+ ) ;
775
+ }
638
776
}
0 commit comments