use clap::ValueEnum;
use serde::Serialize;
use super::pin::PIN_PREFIX;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, ValueEnum)]
#[serde(rename_all = "kebab-case")]
#[value(rename_all = "kebab-case")]
pub enum Venue {
Crates,
Flake,
GithubRelease,
}
pub const SYSTEM_PACKAGE_REASON: &str = "system-package-unpinnable";
impl Venue {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Crates => "crates",
Self::Flake => "flake",
Self::GithubRelease => "github-release",
}
}
pub const ALL: [Self; 3] = [Self::Crates, Self::Flake, Self::GithubRelease];
#[must_use]
pub fn owner_repo() -> &'static str {
PIN_PREFIX
.trim_start_matches("github:")
.trim_end_matches('/')
}
#[must_use]
pub fn reference(self, tag: &str) -> String {
let bare = tag.strip_prefix('v').unwrap_or(tag);
match self {
Self::Crates | Self::GithubRelease => bare.to_owned(),
Self::Flake => format!("{PIN_PREFIX}v{bare}"),
}
}
}
#[cfg(test)]
mod tests {
use super::{SYSTEM_PACKAGE_REASON, Venue};
#[test]
fn the_venue_list_is_closed_and_ordered() {
assert_eq!(Venue::ALL.len(), 3);
let names: Vec<&str> = Venue::ALL.iter().map(|v| v.as_str()).collect();
assert_eq!(names, ["crates", "flake", "github-release"]);
assert_eq!(Venue::owner_repo(), "gubasso/release-kit");
assert!(!SYSTEM_PACKAGE_REASON.is_empty());
}
#[test]
fn each_venue_renders_its_reference_form() {
assert_eq!(Venue::Crates.reference("v0.2.16"), "0.2.16");
assert_eq!(Venue::GithubRelease.reference("0.2.16"), "0.2.16");
assert_eq!(
Venue::Flake.reference("0.2.16"),
"github:gubasso/release-kit/v0.2.16"
);
assert_eq!(
Venue::Flake.reference("v0.2.16"),
"github:gubasso/release-kit/v0.2.16",
"the tag takes exactly one v"
);
}
}