use std::borrow::Cow;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct KindId(Cow<'static, str>);
impl KindId {
pub const RUST: Self = Self(Cow::Borrowed("rust"));
pub const NODE: Self = Self(Cow::Borrowed("node"));
pub const BUN: Self = Self(Cow::Borrowed("bun"));
pub const DENO: Self = Self(Cow::Borrowed("deno"));
pub const PYTHON: Self = Self(Cow::Borrowed("python"));
pub const LUA: Self = Self(Cow::Borrowed("lua"));
pub const C: Self = Self(Cow::Borrowed("c"));
pub const CPP: Self = Self(Cow::Borrowed("cpp"));
pub const UNKNOWN: Self = Self(Cow::Borrowed("unknown"));
pub const fn from_static(s: &'static str) -> Self {
Self(Cow::Borrowed(s))
}
pub fn custom(name: impl Into<String>) -> Self {
Self(Cow::Owned(name.into()))
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn parse_builtin(s: &str) -> Option<Self> {
match s {
"rust" => Some(Self::RUST),
"node" => Some(Self::NODE),
"bun" => Some(Self::BUN),
"deno" => Some(Self::DENO),
"python" => Some(Self::PYTHON),
"lua" => Some(Self::LUA),
"c" => Some(Self::C),
"cpp" | "c++" => Some(Self::CPP),
"unknown" => Some(Self::UNKNOWN),
_ => None,
}
}
}
impl fmt::Display for KindId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn const_builtins_have_expected_strings() {
assert_eq!(KindId::RUST.as_str(), "rust");
assert_eq!(KindId::CPP.as_str(), "cpp");
assert_eq!(KindId::UNKNOWN.as_str(), "unknown");
}
#[test]
fn custom_kind_roundtrip() {
let k = KindId::custom("wgsl");
assert_eq!(k.as_str(), "wgsl");
assert_ne!(k, KindId::RUST);
}
#[test]
fn parse_builtin_accepts_cpp_alias() {
assert_eq!(KindId::parse_builtin("c++"), Some(KindId::CPP));
assert_eq!(KindId::parse_builtin("cpp"), Some(KindId::CPP));
}
#[test]
fn parse_builtin_returns_none_for_custom() {
assert_eq!(KindId::parse_builtin("wgsl"), None);
}
#[test]
fn equality_does_not_depend_on_cow_variant() {
assert_eq!(KindId::RUST, KindId::custom("rust"));
}
}