release_kit/self_depend/
venue.rs1use clap::ValueEnum;
13use serde::Serialize;
14
15use super::pin::PIN_PREFIX;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, ValueEnum)]
19#[serde(rename_all = "kebab-case")]
20#[value(rename_all = "kebab-case")]
21pub enum Venue {
22 Crates,
24 Flake,
26 GithubRelease,
28}
29
30pub const SYSTEM_PACKAGE_REASON: &str = "system-package-unpinnable";
34
35impl Venue {
36 #[must_use]
38 pub const fn as_str(self) -> &'static str {
39 match self {
40 Self::Crates => "crates",
41 Self::Flake => "flake",
42 Self::GithubRelease => "github-release",
43 }
44 }
45
46 pub const ALL: [Self; 3] = [Self::Crates, Self::Flake, Self::GithubRelease];
48
49 #[must_use]
53 pub fn owner_repo() -> &'static str {
54 PIN_PREFIX
55 .trim_start_matches("github:")
56 .trim_end_matches('/')
57 }
58
59 #[must_use]
64 pub fn reference(self, tag: &str) -> String {
65 let bare = tag.strip_prefix('v').unwrap_or(tag);
66 match self {
67 Self::Crates | Self::GithubRelease => bare.to_owned(),
68 Self::Flake => format!("{PIN_PREFIX}v{bare}"),
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::{SYSTEM_PACKAGE_REASON, Venue};
76
77 #[test]
78 fn the_venue_list_is_closed_and_ordered() {
79 assert_eq!(Venue::ALL.len(), 3);
80 let names: Vec<&str> = Venue::ALL.iter().map(|v| v.as_str()).collect();
81 assert_eq!(names, ["crates", "flake", "github-release"]);
82 assert_eq!(Venue::owner_repo(), "gubasso/release-kit");
83 assert!(!SYSTEM_PACKAGE_REASON.is_empty());
84 }
85
86 #[test]
87 fn each_venue_renders_its_reference_form() {
88 assert_eq!(Venue::Crates.reference("v0.2.16"), "0.2.16");
89 assert_eq!(Venue::GithubRelease.reference("0.2.16"), "0.2.16");
90 assert_eq!(
91 Venue::Flake.reference("0.2.16"),
92 "github:gubasso/release-kit/v0.2.16"
93 );
94 assert_eq!(
95 Venue::Flake.reference("v0.2.16"),
96 "github:gubasso/release-kit/v0.2.16",
97 "the tag takes exactly one v"
98 );
99 }
100}