@@ -62,6 +62,43 @@ impl<'a> Cmdline<'a> {
6262 let key = ParameterKey ( key. as_ref ( ) ) ;
6363 self . iter ( ) . find ( |p| p. key == key)
6464 }
65+
66+ /// Locate the value of the kernel argument with the given key name.
67+ ///
68+ /// Returns the first value matching the given key, or `None` if not found.
69+ /// Key comparison treats dashes and underscores as equivalent.
70+ pub fn value_of ( & ' a self , key : impl AsRef < [ u8 ] > ) -> Option < & ' a [ u8 ] > {
71+ self . find ( key) . and_then ( |p| p. value )
72+ }
73+
74+ /// Locate the UTF-8 value of the kernel argument with the given key name.
75+ ///
76+ /// Returns the first value matching the given key, or `None` if not found.
77+ /// Key comparison treats dashes and underscores as equivalent.
78+ pub fn value_of_utf8 ( & ' a self , key : & str ) -> Result < Option < & ' a str > , std:: str:: Utf8Error > {
79+ self . value_of ( key) . map ( std:: str:: from_utf8) . transpose ( )
80+ }
81+
82+ /// Find the value of the kernel argument with the provided name, which must be present.
83+ ///
84+ /// Otherwise the same as [`Self::value_of`].
85+ #[ cfg( test) ]
86+ pub fn require_value_of ( & ' a self , key : impl AsRef < [ u8 ] > ) -> Result < & ' a [ u8 ] > {
87+ let key = key. as_ref ( ) ;
88+ self . value_of ( key) . ok_or_else ( || {
89+ let key = String :: from_utf8_lossy ( key) ;
90+ anyhow:: anyhow!( "Failed to find kernel argument '{key}'" )
91+ } )
92+ }
93+
94+ /// Find the value of the kernel argument with the provided name, which must be present.
95+ ///
96+ /// Otherwise the same as [`Self::value_of`].
97+ #[ cfg( test) ]
98+ pub fn require_value_of_utf8 ( & ' a self , key : & str ) -> Result < & ' a str > {
99+ self . value_of_utf8 ( key) ?
100+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find kernel argument '{key}'" ) )
101+ }
65102}
66103
67104/// A single kernel command line parameter key
@@ -342,4 +379,108 @@ mod tests {
342379 assert_eq ! ( p. key. 0 , b"a_b" ) ;
343380 assert_eq ! ( p. value. unwrap( ) , b"2" ) ;
344381 }
382+
383+ #[ test]
384+ fn test_value_of ( ) {
385+ let kargs = Cmdline :: from ( b"foo=bar baz=qux switch" . as_slice ( ) ) ;
386+
387+ // Test existing key with value
388+ assert_eq ! ( kargs. value_of( "foo" ) , Some ( b"bar" . as_slice( ) ) ) ;
389+ assert_eq ! ( kargs. value_of( "baz" ) , Some ( b"qux" . as_slice( ) ) ) ;
390+
391+ // Test key without value
392+ assert_eq ! ( kargs. value_of( "switch" ) , None ) ;
393+
394+ // Test non-existent key
395+ assert_eq ! ( kargs. value_of( "missing" ) , None ) ;
396+
397+ // Test dash/underscore equivalence
398+ let kargs = Cmdline :: from ( b"dash-key=value1 under_key=value2" . as_slice ( ) ) ;
399+ assert_eq ! ( kargs. value_of( "dash_key" ) , Some ( b"value1" . as_slice( ) ) ) ;
400+ assert_eq ! ( kargs. value_of( "under-key" ) , Some ( b"value2" . as_slice( ) ) ) ;
401+ }
402+
403+ #[ test]
404+ fn test_value_of_utf8 ( ) {
405+ let kargs = Cmdline :: from ( b"foo=bar baz=qux switch" . as_slice ( ) ) ;
406+
407+ // Test existing key with UTF-8 value
408+ assert_eq ! ( kargs. value_of_utf8( "foo" ) . unwrap( ) , Some ( "bar" ) ) ;
409+ assert_eq ! ( kargs. value_of_utf8( "baz" ) . unwrap( ) , Some ( "qux" ) ) ;
410+
411+ // Test key without value
412+ assert_eq ! ( kargs. value_of_utf8( "switch" ) . unwrap( ) , None ) ;
413+
414+ // Test non-existent key
415+ assert_eq ! ( kargs. value_of_utf8( "missing" ) . unwrap( ) , None ) ;
416+
417+ // Test dash/underscore equivalence
418+ let kargs = Cmdline :: from ( b"dash-key=value1 under_key=value2" . as_slice ( ) ) ;
419+ assert_eq ! ( kargs. value_of_utf8( "dash_key" ) . unwrap( ) , Some ( "value1" ) ) ;
420+ assert_eq ! ( kargs. value_of_utf8( "under-key" ) . unwrap( ) , Some ( "value2" ) ) ;
421+
422+ // Test invalid UTF-8
423+ let mut invalid_utf8 = b"invalid=" . to_vec ( ) ;
424+ invalid_utf8. push ( 0xff ) ;
425+ let kargs = Cmdline :: from ( & invalid_utf8) ;
426+ assert ! ( kargs. value_of_utf8( "invalid" ) . is_err( ) ) ;
427+ }
428+
429+ #[ test]
430+ fn test_require_value_of ( ) {
431+ let kargs = Cmdline :: from ( b"foo=bar baz=qux switch" . as_slice ( ) ) ;
432+
433+ // Test existing key with value
434+ assert_eq ! ( kargs. require_value_of( "foo" ) . unwrap( ) , b"bar" ) ;
435+ assert_eq ! ( kargs. require_value_of( "baz" ) . unwrap( ) , b"qux" ) ;
436+
437+ // Test key without value should fail
438+ let err = kargs. require_value_of ( "switch" ) . unwrap_err ( ) ;
439+ assert ! ( err
440+ . to_string( )
441+ . contains( "Failed to find kernel argument 'switch'" ) ) ;
442+
443+ // Test non-existent key should fail
444+ let err = kargs. require_value_of ( "missing" ) . unwrap_err ( ) ;
445+ assert ! ( err
446+ . to_string( )
447+ . contains( "Failed to find kernel argument 'missing'" ) ) ;
448+
449+ // Test dash/underscore equivalence
450+ let kargs = Cmdline :: from ( b"dash-key=value1 under_key=value2" . as_slice ( ) ) ;
451+ assert_eq ! ( kargs. require_value_of( "dash_key" ) . unwrap( ) , b"value1" ) ;
452+ assert_eq ! ( kargs. require_value_of( "under-key" ) . unwrap( ) , b"value2" ) ;
453+ }
454+
455+ #[ test]
456+ fn test_require_value_of_utf8 ( ) {
457+ let kargs = Cmdline :: from ( b"foo=bar baz=qux switch" . as_slice ( ) ) ;
458+
459+ // Test existing key with UTF-8 value
460+ assert_eq ! ( kargs. require_value_of_utf8( "foo" ) . unwrap( ) , "bar" ) ;
461+ assert_eq ! ( kargs. require_value_of_utf8( "baz" ) . unwrap( ) , "qux" ) ;
462+
463+ // Test key without value should fail
464+ let err = kargs. require_value_of_utf8 ( "switch" ) . unwrap_err ( ) ;
465+ assert ! ( err
466+ . to_string( )
467+ . contains( "Failed to find kernel argument 'switch'" ) ) ;
468+
469+ // Test non-existent key should fail
470+ let err = kargs. require_value_of_utf8 ( "missing" ) . unwrap_err ( ) ;
471+ assert ! ( err
472+ . to_string( )
473+ . contains( "Failed to find kernel argument 'missing'" ) ) ;
474+
475+ // Test dash/underscore equivalence
476+ let kargs = Cmdline :: from ( b"dash-key=value1 under_key=value2" . as_slice ( ) ) ;
477+ assert_eq ! ( kargs. require_value_of_utf8( "dash_key" ) . unwrap( ) , "value1" ) ;
478+ assert_eq ! ( kargs. require_value_of_utf8( "under-key" ) . unwrap( ) , "value2" ) ;
479+
480+ // Test invalid UTF-8 should fail
481+ let mut invalid_utf8 = b"invalid=" . to_vec ( ) ;
482+ invalid_utf8. push ( 0xff ) ;
483+ let kargs = Cmdline :: from ( & invalid_utf8) ;
484+ assert ! ( kargs. require_value_of_utf8( "invalid" ) . is_err( ) ) ;
485+ }
345486}
0 commit comments