@@ -59,29 +59,56 @@ impl<'a> Cmdline<'a> {
5959 /// Returns the first parameter matching the given key, or `None` if not found.
6060 /// Key comparison treats dashes and underscores as equivalent.
6161 pub fn find ( & ' a self , key : impl AsRef < [ u8 ] > ) -> Option < Parameter < ' a > > {
62- let key = key. as_ref ( ) ;
62+ let key = ParameterKey ( key. as_ref ( ) ) ;
6363 self . iter ( ) . find ( |p| p. key == key)
6464 }
6565}
6666
67- /// A single kernel command line parameter.
67+ /// A single kernel command line parameter key
6868///
69- /// Can represent either a simple switch (key only) or a key-value pair.
7069/// Handles quoted values and treats dashes and underscores in keys as equivalent.
7170#[ derive( Debug , Eq ) ]
71+ pub ( crate ) struct ParameterKey < ' a > ( pub & ' a [ u8 ] ) ;
72+
73+ impl < ' a > From < & ' a [ u8 ] > for ParameterKey < ' a > {
74+ fn from ( value : & ' a [ u8 ] ) -> Self {
75+ Self ( value)
76+ }
77+ }
78+
79+ /// A single kernel command line parameter.
80+ #[ derive( Debug , PartialEq , Eq ) ]
7281pub ( crate ) struct Parameter < ' a > {
7382 /// The parameter key as raw bytes
74- pub key : & ' a [ u8 ] ,
83+ pub key : ParameterKey < ' a > ,
7584 /// The parameter value as raw bytes, if present
7685 pub value : Option < & ' a [ u8 ] > ,
7786}
7887
7988impl < ' a > Parameter < ' a > {
89+ /// Create a new parameter with the provided key and value.
90+ #[ cfg( test) ]
91+ pub fn new_kv < ' k : ' a , ' v : ' a > ( key : & ' k [ u8 ] , value : & ' v [ u8 ] ) -> Self {
92+ Self {
93+ key : ParameterKey ( key) ,
94+ value : Some ( value) ,
95+ }
96+ }
97+
98+ /// Create a new parameter with the provided key.
99+ #[ cfg( test) ]
100+ pub fn new_key ( key : & ' a [ u8 ] ) -> Self {
101+ Self {
102+ key : ParameterKey ( key) ,
103+ value : None ,
104+ }
105+ }
106+
80107 /// Returns the key as a lossy UTF-8 string.
81108 ///
82109 /// Invalid UTF-8 sequences are replaced with the Unicode replacement character.
83110 pub fn key_lossy ( & self ) -> String {
84- String :: from_utf8_lossy ( self . key ) . to_string ( )
111+ String :: from_utf8_lossy ( self . key . 0 ) . to_string ( )
85112 }
86113
87114 /// Returns the value as a lossy UTF-8 string.
@@ -105,11 +132,12 @@ impl<'a, T: AsRef<[u8]> + ?Sized> From<&'a T> for Parameter<'a> {
105132
106133 match equals {
107134 None => Self {
108- key : input,
135+ key : ParameterKey ( input) ,
109136 value : None ,
110137 } ,
111138 Some ( i) => {
112139 let ( key, mut value) = input. split_at ( i) ;
140+ let key = ParameterKey ( key) ;
113141
114142 // skip `=`, we know it's the first byte because we
115143 // found it above
@@ -131,7 +159,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> From<&'a T> for Parameter<'a> {
131159 }
132160}
133161
134- impl PartialEq for Parameter < ' _ > {
162+ impl PartialEq for ParameterKey < ' _ > {
135163 /// Compares two parameters for equality.
136164 ///
137165 /// Keys are compared with dashes and underscores treated as equivalent.
@@ -150,17 +178,9 @@ impl PartialEq for Parameter<'_> {
150178 //
151179 // For example, "foo" == "foobar" since the zipped iterator
152180 // only compares the first three chars.
153- let our_iter = self . key . iter ( ) . map ( dedashed) ;
154- let other_iter = other. key . iter ( ) . map ( dedashed) ;
155- if !our_iter. eq ( other_iter) {
156- return false ;
157- }
158-
159- match ( self . value , other. value ) {
160- ( Some ( ours) , Some ( other) ) => ours == other,
161- ( None , None ) => true ,
162- _ => false ,
163- }
181+ let our_iter = self . 0 . iter ( ) . map ( dedashed) ;
182+ let other_iter = other. 0 . iter ( ) . map ( dedashed) ;
183+ our_iter. eq ( other_iter)
164184 }
165185}
166186
@@ -194,11 +214,11 @@ mod tests {
194214 #[ test]
195215 fn test_parameter_simple ( ) {
196216 let switch = Parameter :: from ( "foo" ) ;
197- assert_eq ! ( switch. key, b"foo" ) ;
217+ assert_eq ! ( switch. key. 0 , b"foo" ) ;
198218 assert_eq ! ( switch. value, None ) ;
199219
200220 let kv = Parameter :: from ( "bar=baz" ) ;
201- assert_eq ! ( kv. key, b"bar" ) ;
221+ assert_eq ! ( kv. key. 0 , b"bar" ) ;
202222 assert_eq ! ( kv. value, Some ( b"baz" . as_slice( ) ) ) ;
203223 }
204224
@@ -214,7 +234,7 @@ mod tests {
214234
215235 // quotes don't get removed from keys
216236 let p = Parameter :: from ( "\" \" \" " ) ;
217- assert_eq ! ( p. key, b"\" \" \" " ) ;
237+ assert_eq ! ( p. key. 0 , b"\" \" \" " ) ;
218238
219239 // quotes only get stripped from the absolute ends of values
220240 let p = Parameter :: from ( "foo=\" internal \" quotes \" are ok\" " ) ;
@@ -270,30 +290,14 @@ mod tests {
270290 let kargs = Cmdline :: from ( b"foo=bar,bar2 baz=fuz wiz" . as_slice ( ) ) ;
271291 let mut iter = kargs. iter ( ) ;
272292
273- assert_eq ! (
274- iter. next( ) ,
275- Some ( Parameter {
276- key: b"foo" ,
277- value: Some ( b"bar,bar2" . as_slice( ) )
278- } )
279- ) ;
280-
281- assert_eq ! (
282- iter. next( ) ,
283- Some ( Parameter {
284- key: b"baz" ,
285- value: Some ( b"fuz" . as_slice( ) )
286- } )
287- ) ;
293+ assert_eq ! ( iter. next( ) , Some ( Parameter :: new_kv( b"foo" , b"bar,bar2" ) ) ) ;
288294
289295 assert_eq ! (
290296 iter. next( ) ,
291- Some ( Parameter {
292- key: b"wiz" ,
293- value: None ,
294- } )
297+ Some ( Parameter :: new_kv( b"baz" , b"fuz" . as_slice( ) ) )
295298 ) ;
296299
300+ assert_eq ! ( iter. next( ) , Some ( Parameter :: new_key( b"wiz" ) ) ) ;
297301 assert_eq ! ( iter. next( ) , None ) ;
298302
299303 // Test the find API
@@ -310,4 +314,25 @@ mod tests {
310314 // tests are running
311315 assert ! ( kargs. iter( ) . count( ) > 0 ) ;
312316 }
317+
318+ #[ test]
319+ fn test_kargs_find_dash_hyphen ( ) {
320+ let kargs = Cmdline :: from ( b"a-b=1 a_b=2" . as_slice ( ) ) ;
321+ // find should find the first one, which is a-b=1
322+ let p = kargs. find ( "a_b" ) . unwrap ( ) ;
323+ assert_eq ! ( p. key. 0 , b"a-b" ) ;
324+ assert_eq ! ( p. value. unwrap( ) , b"1" ) ;
325+ let p = kargs. find ( "a-b" ) . unwrap ( ) ;
326+ assert_eq ! ( p. key. 0 , b"a-b" ) ;
327+ assert_eq ! ( p. value. unwrap( ) , b"1" ) ;
328+
329+ let kargs = Cmdline :: from ( b"a_b=2 a-b=1" . as_slice ( ) ) ;
330+ // find should find the first one, which is a_b=2
331+ let p = kargs. find ( "a_b" ) . unwrap ( ) ;
332+ assert_eq ! ( p. key. 0 , b"a_b" ) ;
333+ assert_eq ! ( p. value. unwrap( ) , b"2" ) ;
334+ let p = kargs. find ( "a-b" ) . unwrap ( ) ;
335+ assert_eq ! ( p. key. 0 , b"a_b" ) ;
336+ assert_eq ! ( p. value. unwrap( ) , b"2" ) ;
337+ }
313338}
0 commit comments