From 76aefefc41c9a55217768bc0c89a55178db65b47 Mon Sep 17 00:00:00 2001 From: Alvise Rigo Date: Wed, 18 Oct 2023 09:54:09 +0000 Subject: [PATCH] implement TryFrom<&Cmdline> for String In some cases, having a String representation of the Linux command line can be useful. This is the case of vmm-reference which otherwise would require a conversion dance between string types. Signed-off-by: Alvise Rigo --- src/cmdline/mod.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/cmdline/mod.rs b/src/cmdline/mod.rs index 2ac7c312..5d63e1a2 100644 --- a/src/cmdline/mod.rs +++ b/src/cmdline/mod.rs @@ -516,6 +516,37 @@ impl Cmdline { } } +/// Convert a Cmdline to String +/// +/// # Examples +/// +/// ```rust +/// # use linux_loader::cmdline::*; +/// let mut cl = Cmdline::new(20).unwrap(); +/// cl.insert_str("foo").unwrap(); +/// cl.insert_init_args("bar").unwrap(); +/// assert_eq!(String::try_from(&cl).unwrap(), "foo -- bar"); +/// ``` +impl TryFrom<&Cmdline> for String { + type Error = Error; + + fn try_from(value: &Cmdline) -> result::Result { + if value.boot_args.is_empty() && value.init_args.is_empty() { + Ok("".to_string()) + } else if value.boot_args.is_empty() { + Err(Error::NoBootArgsInserted) + } else if value.init_args.is_empty() { + Ok(value.boot_args.to_string()) + } else { + Ok(format!( + "{}{}{}", + value.boot_args, INIT_ARGS_SEPARATOR, value.init_args + ) + .to_string()) + } + } +} + impl TryFrom for Vec { type Error = Error; @@ -867,4 +898,24 @@ mod tests { b"console=ttyS0 nomodules -- /etc/password --param\0" ); } + + #[test] + fn test_string_from_cmdline() { + let mut cl = Cmdline::new(CMDLINE_MAX_SIZE).unwrap(); + + assert_eq!(String::try_from(&cl).unwrap(), ""); + cl.insert_init_args("bar").unwrap(); + // This must fail as it is not allowed to have only init args + let err = String::try_from(&cl).unwrap_err(); + assert_eq!(err, Error::NoBootArgsInserted); + + // However, inserting only bootargs is permitted + cl = Cmdline::new(CMDLINE_MAX_SIZE).unwrap(); + cl.insert_str("foo").unwrap(); + assert_eq!(String::try_from(&cl).unwrap(), "foo"); + + // Test also the concatenation of arguments + cl.insert_init_args("bar").unwrap(); + assert_eq!(String::try_from(&cl).unwrap(), "foo -- bar"); + } }