1use serde::{Deserialize, Serialize};
8use std::fmt;
9use std::str::FromStr;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
38#[serde(rename_all = "snake_case")]
39pub enum PackageType {
40 About,
41 Alpm,
42 Alpine,
43 Android,
44 AndroidLib,
45 Autotools,
46 Axis2,
47 Bazel,
48 Bower,
49 Buck,
50 Cab,
51 Cargo,
52 Chef,
53 Chrome,
54 Cocoapods,
55 Composer,
56 Conan,
57 Conda,
58 Cpan,
59 Cran,
60 Dart,
61 Deb,
62 Deno,
63 Docker,
64 Dmg,
65 Ear,
66 Freebsd,
67 Gem,
68 Github,
69 Golang,
70 Hackage,
71 Haxe,
72 Helm,
73 Hex,
74 Installshield,
75 Ios,
76 Iso,
77 Ivy,
78 Jar,
79 #[serde(rename = "jboss-service")]
80 JbossService,
81 #[serde(rename = "linux-distro")]
82 LinuxDistro,
83 Maven,
84 Meson,
85 Meteor,
86 Mozilla,
87 Npm,
88 Nsis,
89 Nuget,
90 Opam,
91 Osgi,
92 #[serde(rename = "pnpm-lock")]
93 PnpmLock,
94 Pubspec,
95 Pypi,
96 Pixi,
97 Readme,
98 Rpm,
99 Shar,
100 Squashfs,
101 Swift,
102 Vcpkg,
103 War,
104 #[serde(rename = "windows-update")]
105 WindowsUpdate,
106}
107
108impl PackageType {
109 pub fn as_str(&self) -> &'static str {
113 match self {
114 Self::About => "about",
115 Self::Alpm => "alpm",
116 Self::Alpine => "alpine",
117 Self::Android => "android",
118 Self::AndroidLib => "android_lib",
119 Self::Autotools => "autotools",
120 Self::Axis2 => "axis2",
121 Self::Bazel => "bazel",
122 Self::Bower => "bower",
123 Self::Buck => "buck",
124 Self::Cab => "cab",
125 Self::Cargo => "cargo",
126 Self::Chef => "chef",
127 Self::Chrome => "chrome",
128 Self::Cocoapods => "cocoapods",
129 Self::Composer => "composer",
130 Self::Conan => "conan",
131 Self::Conda => "conda",
132 Self::Cpan => "cpan",
133 Self::Cran => "cran",
134 Self::Dart => "dart",
135 Self::Deb => "deb",
136 Self::Deno => "deno",
137 Self::Docker => "docker",
138 Self::Dmg => "dmg",
139 Self::Ear => "ear",
140 Self::Freebsd => "freebsd",
141 Self::Gem => "gem",
142 Self::Github => "github",
143 Self::Golang => "golang",
144 Self::Hackage => "hackage",
145 Self::Haxe => "haxe",
146 Self::Helm => "helm",
147 Self::Hex => "hex",
148 Self::Installshield => "installshield",
149 Self::Ios => "ios",
150 Self::Iso => "iso",
151 Self::Ivy => "ivy",
152 Self::Jar => "jar",
153 Self::JbossService => "jboss-service",
154 Self::LinuxDistro => "linux-distro",
155 Self::Maven => "maven",
156 Self::Meson => "meson",
157 Self::Meteor => "meteor",
158 Self::Mozilla => "mozilla",
159 Self::Npm => "npm",
160 Self::Nsis => "nsis",
161 Self::Nuget => "nuget",
162 Self::Opam => "opam",
163 Self::Osgi => "osgi",
164 Self::PnpmLock => "pnpm-lock",
165 Self::Pubspec => "pubspec",
166 Self::Pypi => "pypi",
167 Self::Pixi => "pixi",
168 Self::Readme => "readme",
169 Self::Rpm => "rpm",
170 Self::Shar => "shar",
171 Self::Squashfs => "squashfs",
172 Self::Swift => "swift",
173 Self::Vcpkg => "vcpkg",
174 Self::War => "war",
175 Self::WindowsUpdate => "windows-update",
176 }
177 }
178}
179
180impl AsRef<str> for PackageType {
181 fn as_ref(&self) -> &str {
182 self.as_str()
183 }
184}
185
186impl fmt::Display for PackageType {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 f.write_str(self.as_str())
189 }
190}
191
192impl FromStr for PackageType {
193 type Err = String;
194
195 fn from_str(s: &str) -> Result<Self, Self::Err> {
196 let json = format!("\"{}\"", s);
197 serde_json::from_str(&json).map_err(|_| format!("unknown package type: {}", s))
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204
205 #[test]
206 fn test_serialization() {
207 let pt = PackageType::Npm;
208 let json = serde_json::to_string(&pt).unwrap();
209 assert_eq!(json, r#""npm""#);
210 }
211
212 #[test]
213 fn test_deserialization() {
214 let json = r#""npm""#;
215 let pt: PackageType = serde_json::from_str(json).unwrap();
216 assert_eq!(pt, PackageType::Npm);
217 }
218
219 #[test]
220 fn test_as_str() {
221 assert_eq!(PackageType::Npm.as_str(), "npm");
222 assert_eq!(PackageType::Cargo.as_str(), "cargo");
223 assert_eq!(PackageType::Pypi.as_str(), "pypi");
224 assert_eq!(PackageType::Alpm.as_str(), "alpm");
225 assert_eq!(PackageType::Vcpkg.as_str(), "vcpkg");
226 assert_eq!(PackageType::Hackage.as_str(), "hackage");
227 assert_eq!(PackageType::Hex.as_str(), "hex");
228 }
229
230 #[test]
231 fn test_display() {
232 assert_eq!(PackageType::Npm.to_string(), "npm");
233 }
234
235 #[test]
236 fn test_as_ref() {
237 let pt = PackageType::Npm;
238 let s: &str = pt.as_ref();
239 assert_eq!(s, "npm");
240 }
241
242 #[test]
243 fn test_kebab_case_variants() {
244 assert_eq!(PackageType::JbossService.as_str(), "jboss-service");
245 assert_eq!(PackageType::LinuxDistro.as_str(), "linux-distro");
246 assert_eq!(PackageType::PnpmLock.as_str(), "pnpm-lock");
247 assert_eq!(PackageType::WindowsUpdate.as_str(), "windows-update");
248
249 let json = serde_json::to_string(&PackageType::JbossService).unwrap();
251 assert_eq!(json, r#""jboss-service""#);
252
253 let json = serde_json::to_string(&PackageType::LinuxDistro).unwrap();
254 assert_eq!(json, r#""linux-distro""#);
255
256 let json = serde_json::to_string(&PackageType::PnpmLock).unwrap();
257 assert_eq!(json, r#""pnpm-lock""#);
258
259 let json = serde_json::to_string(&PackageType::WindowsUpdate).unwrap();
260 assert_eq!(json, r#""windows-update""#);
261 }
262
263 #[test]
264 fn test_snake_case_variant() {
265 assert_eq!(PackageType::AndroidLib.as_str(), "android_lib");
266
267 let json = serde_json::to_string(&PackageType::AndroidLib).unwrap();
268 assert_eq!(json, r#""android_lib""#);
269 }
270
271 #[test]
272 fn test_deserialization_kebab_case() {
273 let pt: PackageType = serde_json::from_str(r#""jboss-service""#).unwrap();
274 assert_eq!(pt, PackageType::JbossService);
275
276 let pt: PackageType = serde_json::from_str(r#""linux-distro""#).unwrap();
277 assert_eq!(pt, PackageType::LinuxDistro);
278
279 let pt: PackageType = serde_json::from_str(r#""pnpm-lock""#).unwrap();
280 assert_eq!(pt, PackageType::PnpmLock);
281
282 let pt: PackageType = serde_json::from_str(r#""windows-update""#).unwrap();
283 assert_eq!(pt, PackageType::WindowsUpdate);
284 }
285}