axbuild 0.1.1

An OS build lib toolkit used by arceos
Documentation
use std::path::PathBuf;

use ostool::build::config::Cargo;

use crate::context::{
    AppContext, QemuRunConfig, ResolvedAxvisorRequest, ResolvedBuildRequest, ResolvedStarryRequest,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SnapshotPersistence {
    Discard,
    Store,
}

pub(crate) trait CommandRequest {
    fn build_info_path(&self) -> PathBuf;
    fn uboot_config(&self) -> Option<PathBuf>;
}

impl CommandRequest for ResolvedBuildRequest {
    fn build_info_path(&self) -> PathBuf {
        self.build_info_path.clone()
    }

    fn uboot_config(&self) -> Option<PathBuf> {
        self.uboot_config.clone()
    }
}

impl CommandRequest for ResolvedStarryRequest {
    fn build_info_path(&self) -> PathBuf {
        self.build_info_path.clone()
    }

    fn uboot_config(&self) -> Option<PathBuf> {
        self.uboot_config.clone()
    }
}

impl CommandRequest for ResolvedAxvisorRequest {
    fn build_info_path(&self) -> PathBuf {
        self.build_info_path.clone()
    }

    fn uboot_config(&self) -> Option<PathBuf> {
        self.uboot_config.clone()
    }
}

pub(crate) fn resolve_request<R, S, Prepare, Store>(
    persistence: SnapshotPersistence,
    prepare: Prepare,
    store: Store,
) -> anyhow::Result<R>
where
    Prepare: FnOnce() -> anyhow::Result<(R, S)>,
    Store: FnOnce(&S) -> anyhow::Result<PathBuf>,
{
    let (request, snapshot) = prepare()?;
    if matches!(persistence, SnapshotPersistence::Store) {
        store(&snapshot)?;
    }
    Ok(request)
}

pub(crate) async fn run_build<R, LoadCargo>(
    app: &mut AppContext,
    request: R,
    load_cargo: LoadCargo,
) -> anyhow::Result<()>
where
    R: CommandRequest,
    LoadCargo: FnOnce(&R) -> anyhow::Result<Cargo>,
{
    let cargo = load_cargo(&request)?;
    app.build(cargo, request.build_info_path()).await
}

pub(crate) async fn run_qemu<R, LoadCargo, LoadQemu>(
    app: &mut AppContext,
    request: R,
    load_cargo: LoadCargo,
    load_qemu: LoadQemu,
) -> anyhow::Result<()>
where
    R: CommandRequest,
    LoadCargo: FnOnce(&R) -> anyhow::Result<Cargo>,
    LoadQemu: FnOnce(&R) -> anyhow::Result<QemuRunConfig>,
{
    let cargo = load_cargo(&request)?;
    let qemu = load_qemu(&request)?;
    app.qemu(cargo, request.build_info_path(), qemu).await
}

pub(crate) async fn run_uboot<R, LoadCargo>(
    app: &mut AppContext,
    request: R,
    load_cargo: LoadCargo,
) -> anyhow::Result<()>
where
    R: CommandRequest,
    LoadCargo: FnOnce(&R) -> anyhow::Result<Cargo>,
{
    let cargo = load_cargo(&request)?;
    app.uboot(cargo, request.build_info_path(), request.uboot_config())
        .await
}