1
1
use serde:: Deserializer ;
2
- use serde:: de:: { Error , Unexpected , Visitor } ;
2
+ use serde:: de:: Visitor ;
3
3
use std:: collections:: HashMap ;
4
4
use std:: fmt:: Formatter ;
5
5
use std:: hash:: BuildHasher ;
@@ -36,23 +36,24 @@ impl<'de, T: From<String>> Visitor<'de> for VectorVisitor<T> {
36
36
}
37
37
38
38
impl < ' de , S : BuildHasher + Default > Visitor < ' de > for MapVisitor < S > {
39
- type Value = HashMap < String , String , S > ;
39
+ type Value = HashMap < String , Option < String > , S > ;
40
40
41
41
fn expecting ( & self , formatter : & mut Formatter ) -> std:: fmt:: Result {
42
42
formatter. write_str (
43
- "either a sequence, or a comma or newline separated string of key=value entries" ,
43
+ "either a sequence, or a comma or newline separated string of key[ =value] entries" ,
44
44
)
45
45
}
46
46
47
47
fn visit_str < E : serde:: de:: Error > ( self , value : & str ) -> Result < Self :: Value , E > {
48
- value
48
+ Ok ( value
49
49
. split ( [ '\n' , ',' ] )
50
50
. map ( |s| {
51
- s. split_once ( '=' )
52
- . ok_or_else ( || E :: custom ( format ! ( "key=value expected, found {s}" ) ) )
53
- . map ( |( key, value) | ( key. to_owned ( ) , value. to_owned ( ) ) )
51
+ match s. split_once ( '=' ) {
52
+ Some ( ( key, value) ) => ( key. to_owned ( ) , Some ( value. to_owned ( ) ) ) ,
53
+ None => ( s. to_owned ( ) , None ) ,
54
+ }
54
55
} )
55
- . collect ( )
56
+ . collect ( ) )
56
57
}
57
58
58
59
fn visit_seq < A > ( self , mut seq : A ) -> Result < Self :: Value , A :: Error >
@@ -61,10 +62,14 @@ impl<'de, S: BuildHasher + Default> Visitor<'de> for MapVisitor<S> {
61
62
{
62
63
let mut ret = HashMap :: with_hasher ( Default :: default ( ) ) ;
63
64
while let Some ( el) = seq. next_element :: < String > ( ) ? {
64
- let ( key, value) = el
65
- . split_once ( '=' )
66
- . ok_or_else ( || A :: Error :: invalid_value ( Unexpected :: Str ( & el) , & self ) ) ?;
67
- ret. insert ( key. to_owned ( ) , value. to_owned ( ) ) ;
65
+ match el. split_once ( '=' ) {
66
+ None => {
67
+ ret. insert ( el. to_owned ( ) , None ) ;
68
+ }
69
+ Some ( ( key, value) ) => {
70
+ ret. insert ( key. to_owned ( ) , Some ( value. to_owned ( ) ) ) ;
71
+ }
72
+ }
68
73
}
69
74
Ok ( ret)
70
75
}
@@ -83,7 +88,7 @@ pub(crate) fn deserialize_newline_or_comma_separated_vec<
83
88
deserializer. deserialize_seq ( VectorVisitor ( PhantomData ) )
84
89
}
85
90
86
- /// deserialize into a map of `String`s to `String`s either of:
91
+ /// deserialize into a map of `String`s to `Option< String> `s either of:
87
92
/// * a sequence of elements serializable into `String`s, or
88
93
/// * a single element serializable into `String`, then split on `,` and `\n`
89
94
pub ( crate ) fn deserialize_newline_or_comma_separated_map <
@@ -92,6 +97,6 @@ pub(crate) fn deserialize_newline_or_comma_separated_map<
92
97
S : BuildHasher + Default ,
93
98
> (
94
99
deserializer : D ,
95
- ) -> Result < HashMap < String , String , S > , D :: Error > {
100
+ ) -> Result < HashMap < String , Option < String > , S > , D :: Error > {
96
101
deserializer. deserialize_map ( MapVisitor ( PhantomData ) )
97
102
}
0 commit comments