alien_core/
access_request_crd.rs1pub const DEFAULT_BRAND: &str = "alien";
28
29#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct AccessRequestCrdNames {
32 pub group: String,
34 pub kind: String,
36 pub plural: String,
38 pub singular: String,
40 pub short_name: String,
42 pub api_version: String,
44 pub crd_name: String,
47}
48
49pub const ACCESS_REQUEST_CRD_VERSION: &str = "v1alpha1";
51
52pub fn access_request_crd_names(brand_name: Option<&str>) -> AccessRequestCrdNames {
59 let name = brand_name
60 .map(str::trim)
61 .filter(|n| !n.is_empty())
62 .unwrap_or(DEFAULT_BRAND);
63
64 let brand = brand_slug(name);
65 let group = format!("accessrequests.{brand}");
66 let plural = format!("{brand}accessrequests");
67 let singular = format!("{brand}accessrequest");
68 let short_name = format!("{brand}ar");
69 let kind = format!("{}AccessRequest", capitalize(&brand));
70
71 AccessRequestCrdNames {
72 api_version: format!("{group}/{ACCESS_REQUEST_CRD_VERSION}"),
73 crd_name: format!("{plural}.{group}"),
74 group,
75 kind,
76 plural,
77 singular,
78 short_name,
79 }
80}
81
82fn brand_slug(name: &str) -> String {
86 let first_label = name.split('.').next().unwrap_or(name);
87 let slug: String = first_label
88 .chars()
89 .filter(|c| c.is_ascii_alphanumeric())
90 .map(|c| c.to_ascii_lowercase())
91 .collect();
92 if slug.is_empty() {
93 "alien".to_string()
94 } else {
95 slug
96 }
97}
98
99fn capitalize(s: &str) -> String {
101 let mut chars = s.chars();
102 match chars.next() {
103 Some(first) => first.to_ascii_uppercase().to_string() + chars.as_str(),
104 None => String::new(),
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn default_is_alien() {
114 let n = access_request_crd_names(None);
115 assert_eq!(n.group, "accessrequests.alien");
116 assert_eq!(n.kind, "AlienAccessRequest");
117 assert_eq!(n.plural, "alienaccessrequests");
118 assert_eq!(n.short_name, "alienar");
119 assert_eq!(n.crd_name, "alienaccessrequests.accessrequests.alien");
120 assert_eq!(n.api_version, "accessrequests.alien/v1alpha1");
121 }
122
123 #[test]
124 fn brands_from_domain() {
125 let n = access_request_crd_names(Some("acme.dev"));
126 assert_eq!(n.group, "accessrequests.acme");
127 assert_eq!(n.kind, "AcmeAccessRequest");
128 assert_eq!(n.plural, "acmeaccessrequests");
129 assert_eq!(n.singular, "acmeaccessrequest");
130 assert_eq!(n.short_name, "acmear");
131 assert_eq!(n.crd_name, "acmeaccessrequests.accessrequests.acme");
132 }
133
134 #[test]
135 fn brands_from_plain_name() {
136 let n = access_request_crd_names(Some("My Cool App"));
137 assert_eq!(n.group, "accessrequests.mycoolapp");
138 assert_eq!(n.kind, "MycoolappAccessRequest");
139 assert_eq!(n.plural, "mycoolappaccessrequests");
140 assert_eq!(n.short_name, "mycoolappar");
141 }
142
143 #[test]
144 fn plural_is_brand_prefixed_accessrequests() {
145 let n = access_request_crd_names(Some("globex.dev"));
147 assert_eq!(n.plural, "globexaccessrequests");
148 assert_eq!(n.kind, "GlobexAccessRequest");
149 assert_eq!(n.group, "accessrequests.globex");
150 }
151
152 #[test]
153 fn strips_non_alphanumerics_from_slug() {
154 let n = access_request_crd_names(Some("my-startup.io"));
155 assert_eq!(n.group, "accessrequests.mystartup");
156 assert_eq!(n.kind, "MystartupAccessRequest");
157 assert_eq!(n.plural, "mystartupaccessrequests");
158 }
159
160 #[test]
161 fn empty_domain_falls_back() {
162 assert_eq!(
163 access_request_crd_names(Some("")).kind,
164 "AlienAccessRequest"
165 );
166 assert_eq!(
167 access_request_crd_names(Some(" ")).kind,
168 "AlienAccessRequest"
169 );
170 }
171}