use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "kind", content = "name", rename_all = "lowercase"))]
pub enum WorkspaceKindId {
Cargo,
Npm,
Pnpm,
Yarn,
Bun,
Deno,
Go,
Lerna,
Nx,
Turborepo,
Mira,
Custom(String),
}
impl WorkspaceKindId {
pub fn as_slug(&self) -> &str {
match self {
Self::Cargo => "cargo",
Self::Npm => "npm",
Self::Pnpm => "pnpm",
Self::Yarn => "yarn",
Self::Bun => "bun",
Self::Deno => "deno",
Self::Go => "go",
Self::Lerna => "lerna",
Self::Nx => "nx",
Self::Turborepo => "turborepo",
Self::Mira => "mira",
Self::Custom(s) => s.as_str(),
}
}
pub fn from_slug(s: &str) -> Self {
match s {
"cargo" => Self::Cargo,
"npm" => Self::Npm,
"pnpm" => Self::Pnpm,
"yarn" => Self::Yarn,
"bun" => Self::Bun,
"deno" => Self::Deno,
"go" => Self::Go,
"lerna" => Self::Lerna,
"nx" => Self::Nx,
"turborepo" => Self::Turborepo,
"mira" => Self::Mira,
other => Self::Custom(other.to_string()),
}
}
pub fn is_builtin(&self) -> bool {
!matches!(self, Self::Custom(_))
}
}
impl fmt::Display for WorkspaceKindId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_slug())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builtin_slug_roundtrip() {
for kind in [
WorkspaceKindId::Cargo,
WorkspaceKindId::Npm,
WorkspaceKindId::Pnpm,
WorkspaceKindId::Yarn,
WorkspaceKindId::Bun,
WorkspaceKindId::Deno,
WorkspaceKindId::Go,
WorkspaceKindId::Lerna,
WorkspaceKindId::Nx,
WorkspaceKindId::Turborepo,
WorkspaceKindId::Mira,
] {
assert_eq!(WorkspaceKindId::from_slug(kind.as_slug()), kind);
assert!(kind.is_builtin());
}
}
#[test]
fn unknown_slug_becomes_custom() {
let k = WorkspaceKindId::from_slug("bazel");
assert!(!k.is_builtin());
assert_eq!(k.as_slug(), "bazel");
assert_eq!(k, WorkspaceKindId::Custom("bazel".into()));
}
#[test]
fn display_matches_slug() {
assert_eq!(WorkspaceKindId::Cargo.to_string(), "cargo");
assert_eq!(WorkspaceKindId::Custom("buck2".into()).to_string(), "buck2");
}
}