Skip to content

Commit

Permalink
cosmetic changes & doctests
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandra Iordache <[email protected]>
  • Loading branch information
Alexandra Iordache committed Mar 10, 2020
1 parent 0c754f3 commit a271fbe
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 128 deletions.
103 changes: 82 additions & 21 deletions src/cmdline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::fmt;
use std::result;

/// The error type for command line building operations.
#[derive(PartialEq, Debug)]
#[derive(Debug, PartialEq)]
pub enum Error {
/// Operation would have resulted in a non-printable ASCII character.
InvalidAscii,
Expand All @@ -30,16 +30,17 @@ impl fmt::Display for Error {
f,
"{}",
match *self {
Error::InvalidAscii => "string contains non-printable ASCII character",
Error::HasSpace => "string contains a space",
Error::HasEquals => "string contains an equals sign",
Error::TooLarge => "inserting string would make command line too long",
Error::InvalidAscii => "String contains a non-printable ASCII character.",
Error::HasSpace => "String contains a space.",
Error::HasEquals => "String contains an equals sign.",
Error::TooLarge => "Inserting string would make command line too long.",
}
)
}
}

/// Specialized Result type for command line operations.
/// Specialized [`Result`] type for command line operations.
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
pub type Result<T> = result::Result<T, Error>;

fn valid_char(c: char) -> bool {
Expand Down Expand Up @@ -69,17 +70,37 @@ fn valid_element(s: &str) -> Result<()> {
}
}

/// A builder for a kernel command line string that validates the string as its being built. A
/// `CString` can be constructed from this directly using `CString::new`.
#[derive(Clone)]
/// A builder for a kernel command line string that validates the string as it's being built.
/// A `CString` can be constructed from this directly using `CString::new`.
///
/// # Examples
///
/// ```rust
/// # use linux_loader::cmdline::*;
/// # use std::ffi::CString;
/// let cl = Cmdline::new(100);
/// let cl_cstring = CString::new(cl).unwrap();
/// assert_eq!(cl_cstring.to_str().unwrap(), "");
/// ```
pub struct Cmdline {
line: String,
capacity: usize,
}

impl Cmdline {
/// Constructs an empty Cmdline with the given capacity, which includes the nul terminator.
/// Capacity must be greater than 0.
/// Constructs an empty [`Cmdline`] with the given capacity, including the nul terminator.
///
/// # Arguments
///
/// * `capacity` - Command line capacity. Must be greater than 0.
///
/// # Examples
///
/// ```rust
/// # use linux_loader::cmdline::*;
/// let cl = Cmdline::new(100);
/// ```
/// [`Cmdline`]: struct.Cmdline.html
pub fn new(capacity: usize) -> Cmdline {
assert_ne!(capacity, 0);
Cmdline {
Expand Down Expand Up @@ -109,7 +130,23 @@ impl Cmdline {
assert!(self.line.len() < self.capacity);
}

/// Validates and inserts a key value pair into this command line
/// Validates and inserts a key-value pair into this command line.
///
/// # Arguments
///
/// * `key` - Key to be inserted in the command line string.
/// * `val` - Value corresponding to `key`.
///
/// # Examples
///
/// ```rust
/// # use linux_loader::cmdline::*;
/// # use std::ffi::CString;
/// let mut cl = Cmdline::new(100);
/// cl.insert("foo", "bar");
/// let cl_cstring = CString::new(cl).unwrap();
/// assert_eq!(cl_cstring.to_str().unwrap(), "foo=bar");
/// ```
pub fn insert<T: AsRef<str>>(&mut self, key: T, val: T) -> Result<()> {
let k = key.as_ref();
let v = val.as_ref();
Expand All @@ -127,7 +164,22 @@ impl Cmdline {
Ok(())
}

/// Validates and inserts a string to the end of the current command line
/// Validates and inserts a string to the end of the current command line.
///
/// # Arguments
///
/// * `slug` - String to be appended to the command line.
///
/// # Examples
///
/// ```rust
/// # use linux_loader::cmdline::*;
/// # use std::ffi::CString;
/// let mut cl = Cmdline::new(100);
/// cl.insert_str("foobar");
/// let cl_cstring = CString::new(cl).unwrap();
/// assert_eq!(cl_cstring.to_str().unwrap(), "foobar");
/// ```
pub fn insert_str<T: AsRef<str>>(&mut self, slug: T) -> Result<()> {
let s = slug.as_ref();
valid_str(s)?;
Expand All @@ -141,7 +193,16 @@ impl Cmdline {
Ok(())
}

/// Returns the cmdline in progress without nul termination
/// Returns the string representation of the command line without the nul terminator.
///
/// # Examples
///
/// ```rust
/// # use linux_loader::cmdline::*;
/// let mut cl = Cmdline::new(10);
/// cl.insert_str("foobar");
/// assert_eq!(cl.as_str(), "foobar");
/// ```
pub fn as_str(&self) -> &str {
self.line.as_str()
}
Expand All @@ -159,7 +220,7 @@ mod tests {
use std::ffi::CString;

#[test]
fn insert_hello_world() {
fn test_insert_hello_world() {
let mut cl = Cmdline::new(100);
assert_eq!(cl.as_str(), "");
assert!(cl.insert("hello", "world").is_ok());
Expand All @@ -170,15 +231,15 @@ mod tests {
}

#[test]
fn insert_multi() {
fn test_insert_multi() {
let mut cl = Cmdline::new(100);
assert!(cl.insert("hello", "world").is_ok());
assert!(cl.insert("foo", "bar").is_ok());
assert_eq!(cl.as_str(), "hello=world foo=bar");
}

#[test]
fn insert_space() {
fn test_insert_space() {
let mut cl = Cmdline::new(100);
assert_eq!(cl.insert("a ", "b"), Err(Error::HasSpace));
assert_eq!(cl.insert("a", "b "), Err(Error::HasSpace));
Expand All @@ -188,7 +249,7 @@ mod tests {
}

#[test]
fn insert_equals() {
fn test_insert_equals() {
let mut cl = Cmdline::new(100);
assert_eq!(cl.insert("a=", "b"), Err(Error::HasEquals));
assert_eq!(cl.insert("a", "b="), Err(Error::HasEquals));
Expand All @@ -199,15 +260,15 @@ mod tests {
}

#[test]
fn insert_emoji() {
fn test_insert_emoji() {
let mut cl = Cmdline::new(100);
assert_eq!(cl.insert("heart", "💖"), Err(Error::InvalidAscii));
assert_eq!(cl.insert("💖", "love"), Err(Error::InvalidAscii));
assert_eq!(cl.as_str(), "");
}

#[test]
fn insert_string() {
fn test_insert_string() {
let mut cl = Cmdline::new(13);
assert_eq!(cl.as_str(), "");
assert!(cl.insert_str("noapic").is_ok());
Expand All @@ -217,7 +278,7 @@ mod tests {
}

#[test]
fn insert_too_large() {
fn test_insert_too_large() {
let mut cl = Cmdline::new(4);
assert_eq!(cl.insert("hello", "world"), Err(Error::TooLarge));
assert_eq!(cl.insert("a", "world"), Err(Error::TooLarge));
Expand Down
16 changes: 7 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@

//! A Linux kernel image loading crate.
//!
//! This crate offers support for loading raw ELF (vmlinux) and compressed
//! big zImage (bzImage) kernel images.
//! Support for any other kernel image format can be added by implementing
//! the KernelLoader.
//! This crate offers support for loading raw ELF (vmlinux) and compressed big zImage (bzImage)
//! kernel images.
//! Support for any other kernel image format can be added by implementing the [`KernelLoader`].
//!
//! # Platform support
//!
//! - x86_64
//! - `x86_64`
//!
//! This crates only supports x86_64 platforms because it implements support
//! for kernel image formats (vmlinux and bzImage) that are x86 specific.
//! Extending this crate to support other kernel image formats (e.g. ARM's Image) will make it
//! consumable by other platforms.
//!
//! Extending it to support other kernel image formats (e.g. ARM's Image)
//! will make it consumable by other platforms.
//! [`KernelLoader`]: trait.KernelLoader.html
pub mod cmdline;
pub mod loader;
Expand Down
Loading

0 comments on commit a271fbe

Please sign in to comment.