rusta-cli 1.3.0

macOS arm64 CLI for creating and managing Ubuntu VMs on Tart
Documentation
use crate::cli::{ImageAction, ImageArgs};
use crate::error::{Error, Result};
use crate::io as rio;
use crate::registry;
use crate::state;

pub fn run(args: ImageArgs) -> Result<u8> {
    match args.action.unwrap_or(ImageAction::List) {
        ImageAction::List => list(),
        ImageAction::Add { name } => add(&name),
        ImageAction::Rm { name } => rm(&name),
        ImageAction::Move { name, position } => reorder(&name, position),
    }
}

fn list() -> Result<u8> {
    let configured = !state::State::load().images.is_empty();
    let images = state::images();
    rio::info("Images (priority order; first is the create default):");
    for (i, name) in images.iter().enumerate() {
        let marker = if i == 0 { "  (default)" } else { "" };
        println!("  {}. {}{}", i + 1, name, marker);
    }
    if !configured {
        println!();
        rio::skip(&format!(
            "Using the built-in defaults ({}). Add one with `rusta image add <name>`.",
            state::DEFAULT_IMAGES.join(", ")
        ));
    }
    Ok(0)
}

fn add(input: &str) -> Result<u8> {
    let name = registry::validate_image(input)?;
    if state::add_image(&name).map_err(|e| Error::msg(e.to_string()))? {
        rio::ok(&format!("Added image: {name}"));
    } else {
        rio::skip(&format!("Image already configured: {name}"));
    }
    Ok(0)
}

fn rm(input: &str) -> Result<u8> {
    let name = input.trim();
    if state::remove_image(name).map_err(|e| Error::msg(e.to_string()))? {
        rio::ok(&format!("Removed image: {name}"));
        Ok(0)
    } else {
        Err(Error::not_found(format!("image not configured: {name}")))
    }
}

fn reorder(input: &str, position: usize) -> Result<u8> {
    let name = input.trim();
    if state::move_image(name, position).map_err(|e| Error::msg(e.to_string()))? {
        rio::ok(&format!("Moved image {name} to position {position}"));
        Ok(0)
    } else {
        Err(Error::not_found(format!("image not configured: {name}")))
    }
}