@@ -62,6 +62,43 @@ impl<'a> Cmdline<'a> {
62
62
let key = ParameterKey ( key. as_ref ( ) ) ;
63
63
self . iter ( ) . find ( |p| p. key == key)
64
64
}
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
+ }
65
102
}
66
103
67
104
/// A single kernel command line parameter key
@@ -342,4 +379,108 @@ mod tests {
342
379
assert_eq ! ( p. key. 0 , b"a_b" ) ;
343
380
assert_eq ! ( p. value. unwrap( ) , b"2" ) ;
344
381
}
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
+ }
345
486
}
0 commit comments