vboxhelper 0.3.3

API wrapper around VirtualBox's command line tools.
Documentation
use std::process::Command;

use crate::strutils::{buf_to_strlines, EmptyLine};

use crate::Error;


/// Check whether `VBoxControl` is available or not.
pub fn have_control() -> Result<bool, Error> {
  match Command::new("VBoxControl").output() {
    Ok(_) => Ok(true),
    Err(_) => Ok(false)
  }
}


#[derive(Debug)]
pub struct Revisions {
  pub host: u32,
  pub guest_add: u32
}

pub fn get_revisions() -> Result<Revisions, Error> {
  let mut revs = Vec::new();

  for key in [
    "/VirtualBox/HostInfo/VBoxRev",
    "/VirtualBox/GuestAdd/Revision"
  ] {
    let mut cmd = Command::new("VBoxControl");
    cmd.args(["-nologo", "guestproperty", "get"]);
    cmd.arg(key);
    match cmd.output() {
      Ok(output) => {
        let lines = buf_to_strlines(&output.stdout, EmptyLine::Ignore);
        if lines.is_empty() {
          let msg = format!("Missing field: {key}");
          return Err(Error::missing_data(msg));
        }
        let fields: Vec<&str> = lines[0].split(" ").collect();
        let rev = match fields[1].parse::<u32>() {
          Ok(n) => n,
          Err(_) => {
            return Err(Error::BadFormat(
              "Unable to parse revision number".to_string()
            ));
          }
        };
        revs.push(rev);
      }
      Err(_e) => {
        return Err(Error::FailedToExecute(format!("{:?}", cmd)));
      }
    }
  }

  Ok(Revisions {
    host: revs[0],
    guest_add: revs[1]
  })
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :