tagit-workspace 0.1.1

workspace abstraction for tagit
Documentation
use std::{
    fmt::{Debug, Display},
    path::Path,
};

#[doc(hidden)]
pub use inventory;
use semver::Version;
use tagit_cfg::TagitCfg;

pub trait TagitPackage: Display {
    fn manifest_path(&self) -> &Path;
    fn cfg(&self) -> anyhow::Result<TagitCfg>;
    fn name(&self) -> &str;
    fn version(&self) -> &Version;
    fn root(&self) -> &Path;
}

pub trait TagitWorkspace {
    fn members(&self) -> Vec<&dyn TagitPackage>;
    fn root_manifest(&self) -> &Path;
}

pub trait TagitWorkspaceProvider: 'static + Send + Sync + Debug {
    fn with_workspace(
        &self,
        f: &mut dyn FnMut(&dyn TagitWorkspace) -> anyhow::Result<()>,
    ) -> anyhow::Result<()>;
}

#[derive(Debug, Clone)]
#[doc(hidden)]
pub struct WorkspaceProvider(&'static dyn TagitWorkspaceProvider);

impl WorkspaceProvider {
    #[doc(hidden)]
    pub const fn new(provider: &'static impl TagitWorkspaceProvider) -> Self {
        Self(provider)
    }
}

pub fn with_workspaces(
    mut f: impl FnMut(&dyn TagitWorkspace) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
    for provider in inventory::iter::<WorkspaceProvider> {
        provider.0.with_workspace(&mut f)?;
    }
    Ok(())
}

inventory::collect!(WorkspaceProvider);

#[macro_export]
macro_rules! submit {
    ($provider:expr) => {
        $crate::inventory::submit! {
            $crate::WorkspaceProvider::new(&$provider)
        }
    };
}