@@ -24,6 +24,8 @@ pub enum Error {
24
24
HasSpace ,
25
25
/// Key/Value Operation would have had an equals sign in it.
26
26
HasEquals ,
27
+ /// Key/Value Operation was not passed a value.
28
+ MissingVal ( String ) ,
27
29
/// 0-sized virtio MMIO device passed to the kernel command line builder.
28
30
MmioSize ,
29
31
/// Operation would have made the command line too large.
@@ -41,6 +43,7 @@ impl fmt::Display for Error {
41
43
) ,
42
44
Error :: HasSpace => write ! ( f, "String contains a space." ) ,
43
45
Error :: HasEquals => write ! ( f, "String contains an equals sign." ) ,
46
+ Error :: MissingVal ( ref k) => write ! ( f, "Missing value for key {}." , k) ,
44
47
Error :: MmioSize => write ! (
45
48
f,
46
49
"0-sized virtio MMIO device passed to the kernel command line builder."
@@ -178,6 +181,46 @@ impl Cmdline {
178
181
Ok ( ( ) )
179
182
}
180
183
184
+ /// Validates and inserts a key-value1,...,valueN pair into this command line.
185
+ ///
186
+ /// # Arguments
187
+ ///
188
+ /// * `key` - Key to be inserted in the command line string.
189
+ /// * `vals` - Values corresponding to `key`.
190
+ ///
191
+ /// # Examples
192
+ ///
193
+ /// ```rust
194
+ /// # use linux_loader::cmdline::*;
195
+ /// # use std::ffi::CString;
196
+ /// let mut cl = Cmdline::new(100);
197
+ /// cl.insert_multiple("foo", &["bar", "baz"]);
198
+ /// let cl_cstring = CString::new(cl).unwrap();
199
+ /// assert_eq!(cl_cstring.to_str().unwrap(), "foo=bar,baz");
200
+ /// ```
201
+ pub fn insert_multiple < T : AsRef < str > > ( & mut self , key : T , vals : & [ T ] ) -> Result < ( ) > {
202
+ let k = key. as_ref ( ) ;
203
+
204
+ valid_element ( k) ?;
205
+ if vals. is_empty ( ) {
206
+ return Err ( Error :: MissingVal ( k. to_string ( ) ) ) ;
207
+ }
208
+
209
+ let kv_str = format ! (
210
+ "{}={}" ,
211
+ k,
212
+ vals. iter( )
213
+ . map( |v| -> Result <& str > {
214
+ valid_element( v. as_ref( ) ) ?;
215
+ Ok ( v. as_ref( ) )
216
+ } )
217
+ . collect:: <Result <Vec <& str >>>( ) ?
218
+ . join( "," )
219
+ ) ;
220
+
221
+ self . insert_str ( kv_str)
222
+ }
223
+
181
224
/// Validates and inserts a string to the end of the current command line.
182
225
///
183
226
/// # Arguments
@@ -414,4 +457,32 @@ mod tests {
414
457
expected_str. push_str ( " virtio_mmio.device=4G@0x10000:4:42" ) ;
415
458
assert_eq ! ( cl. as_str( ) , & expected_str) ;
416
459
}
460
+
461
+ #[ test]
462
+ fn test_insert_kv ( ) {
463
+ let mut cl = Cmdline :: new ( 10 ) ;
464
+
465
+ let no_vals: Vec < & str > = vec ! [ ] ;
466
+ assert_eq ! ( cl. insert_multiple( "foo=" , & no_vals) , Err ( Error :: HasEquals ) ) ;
467
+ assert_eq ! (
468
+ cl. insert_multiple( "foo" , & no_vals) ,
469
+ Err ( Error :: MissingVal ( "foo" . to_string( ) ) )
470
+ ) ;
471
+ assert_eq ! (
472
+ cl. insert_multiple( "foo" , & vec![ "bar " ] ) ,
473
+ Err ( Error :: HasSpace )
474
+ ) ;
475
+ assert_eq ! (
476
+ cl. insert_multiple( "foo" , & vec![ "bar" , "baz" ] ) ,
477
+ Err ( Error :: TooLarge )
478
+ ) ;
479
+
480
+ let mut cl = Cmdline :: new ( 100 ) ;
481
+ assert ! ( cl. insert_multiple( "foo" , & vec![ "bar" ] ) . is_ok( ) ) ;
482
+ assert_eq ! ( cl. as_str( ) , "foo=bar" ) ;
483
+
484
+ let mut cl = Cmdline :: new ( 100 ) ;
485
+ assert ! ( cl. insert_multiple( "foo" , & vec![ "bar" , "baz" ] ) . is_ok( ) ) ;
486
+ assert_eq ! ( cl. as_str( ) , "foo=bar,baz" ) ;
487
+ }
417
488
}
0 commit comments