vertigo-cli 0.11.4

Reactive Real-DOM library with SSR for Rust - packaging/serving tool
Documentation
use serde::Deserialize;
use std::path::PathBuf;

use crate::commons::{ErrorCode, command::CommandRun};

#[derive(Clone, Debug, Deserialize)]
pub struct Workspace {
    packages: Vec<Package>,
    target_directory: String,
    workspace_members: Vec<String>,
    workspace_root: String,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Package {
    id: String,
    name: String,
    manifest_path: String,
    targets: Vec<Target>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Target {
    kind: Vec<String>,
}

impl Workspace {
    pub fn infer_package_name(&self) -> Option<String> {
        for member_id in &self.workspace_members {
            if let Some(package) = self
                .packages
                .iter()
                .find(|package| &package.id == member_id)
                && package.is_cdylib()
            {
                return Some(package.name.clone());
            }
        }
        None
    }

    pub fn find_package_path(&self, package_name: &str) -> Option<PathBuf> {
        self.packages
            .iter()
            .find(|package| package.name == package_name)
            .map(|package| package.manifest_path.clone().into())
            .and_then(|path: PathBuf| path.parent().map(|p| p.to_path_buf()))
    }

    pub fn get_target_dir(&self) -> PathBuf {
        self.target_directory.clone().into()
    }

    pub fn get_root_dir(&self) -> &str {
        &self.workspace_root
    }
}

impl Package {
    pub fn is_cdylib(&self) -> bool {
        self.targets
            .iter()
            .any(|target| target.kind.iter().any(|kind| kind == "cdylib"))
    }
}

pub fn get_workspace() -> Result<Workspace, ErrorCode> {
    let metadata = CommandRun::new("cargo")
        .add_param("metadata")
        .add_param("--format-version=1")
        .set_error_code(ErrorCode::CantOpenWorkspace)
        .output()?;

    match serde_json::from_str::<Workspace>(&metadata) {
        Ok(mut ws) => {
            // Retain only local packages to keep object thin
            ws.packages
                .retain(|package| ws.workspace_members.contains(&package.id));
            Ok(ws)
        }
        Err(err) => {
            log::error!("Can't parse workspace: {err}");
            Err(ErrorCode::CantParseWorkspace)
        }
    }
}