1use serde::{Deserialize, Serialize};
13use std::fmt;
14use std::str::FromStr;
15use strum::{EnumCount, EnumIter};
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, EnumCount, EnumIter)]
29pub enum DatasourceId {
30 AboutFile,
32 Readme,
33 EtcOsRelease,
34
35 AlpineApkArchive,
37 AlpineApkbuild,
38 AlpineInstalledDb,
39
40 ArchAurinfo,
42 ArchPkginfo,
43 ArchSrcinfo,
44
45 AndroidAab,
47 AndroidAarLibrary,
48 AndroidApk,
49 AndroidManifestXml,
50 AndroidSoongMetadata,
51
52 Axis2Mar,
54 Axis2ModuleXml,
55
56 AutotoolsConfigure,
58
59 BazelBuild,
61 BazelModule,
62
63 BitbakeRecipe,
65 BitbakeRecipeAppend,
66
67 BowerJson,
69
70 BuckFile,
72 BuckMetadata,
73
74 BunLock,
76 BunLockb,
77
78 CarthageCartfile,
80 CarthageCartfileResolved,
81
82 CargoLock,
84 CargoToml,
85 RustBinary,
86 WindowsExecutable,
87
88 ChefCookbookMetadataJson,
91 ChefCookbookMetadataRb,
93
94 CitationCff,
95
96 CocoapodsPodfile,
98 CocoapodsPodfileLock,
99 CocoapodsPodspec,
100 CocoapodsPodspecJson,
101
102 ConanConanDataYml,
104 ConanConanFilePy,
105 ConanConanFileTxt,
106 ConanLock,
107
108 CondaYaml,
111 CondaMetaJson,
112 CondaMetaYaml,
113
114 ClojureDepsEdn,
116 ClojureProjectClj,
117
118 CpanDistIni,
120 CpanMakefile,
122 CpanManifest,
123 CpanMetaJson,
124 CpanMetaYml,
125
126 CranDescription,
128
129 PubspecLock,
131 PubspecYaml,
132
133 DebianControlExtractedDeb,
135 DebianControlInSource,
136 DebianCopyright,
137 DebianCopyrightInSource,
138 DebianCopyrightInPackage,
139 DebianCopyrightStandalone,
140 DebianDeb,
141 DebianSourceMetadataTarball,
143 DebianDistrolessInstalledDb,
144 DebianInstalledFilesList,
146 DebianInstalledMd5Sums,
147 DebianInstalledStatusDb,
148 DebianMd5SumsInExtractedDeb,
149 DebianOriginalSourceTarball,
151 DebianSourceControlDsc,
152
153 DenoJson,
155 DenoLock,
156
157 Dockerfile,
159
160 OciImageIndex,
162 OciImageManifest,
163
164 ErlangOtpAppSrc,
166 RebarConfig,
167 RebarLock,
168
169 FreebsdCompactManifest,
171
172 Godeps,
174 GoBinary,
175 GoMod,
176 GoModGraph,
177 GoSum,
178 GoWork,
179
180 HackageCabal,
182 HackageCabalProject,
183 HackageStackYaml,
184
185 BuildGradle,
187 GradleLockfile,
188 GradleModule,
189
190 HaxelibJson,
192
193 HelmChartLock,
195 HelmChartYaml,
196
197 HexMixLock,
199
200 HuggingfaceModelCard,
202 HuggingfaceConfigJson,
203 HuggingfaceModelIndexJson,
204
205 JuliaProjectToml,
207 JuliaManifestToml,
208
209 AntIvyXml,
211 JavaEarApplicationXml,
212 JavaEarArchive,
213 JavaJar,
214 JavaJarManifest,
215 JavaOsgiManifest,
216 JavaWarArchive,
217 JavaWarWebXml,
218 JbossSar,
219 JbossServiceXml,
220
221 MavenPom,
223 MavenPomProperties,
224 MesonBuild,
225
226 SbtBuildSbt,
227
228 MicrosoftCabinet,
230 MicrosoftUpdateManifestMum,
231
232 AppleDmg,
234 ChromeCrx,
235 IosIpa,
236 MozillaXpi,
237
238 MeteorPackage,
240
241 NixDefaultNix,
242 NixFlakeLock,
243 NixFlakeNix,
244
245 NpmPackageJson,
247 NpmPackageLockJson,
248
249 NugetCsproj,
251 NugetDepsJson,
252 NugetDirectoryBuildProps,
253 NugetDirectoryPackagesProps,
254 NugetNupkg,
255 NugetProjectJson,
256 NugetProjectLockJson,
257 NugetPackagesConfig,
258 NugetPackagesLock,
259 NugetNuspec,
260 NugetVbproj,
261 NugetFsproj,
262
263 OpamFile,
265
266 PhpComposerJson,
268 PhpComposerLock,
269
270 PnpmLockYaml,
272 PnpmWorkspaceYaml,
273
274 Pipfile,
276 PipfileLock,
277 PipRequirements,
278 PixiLock,
279 PixiToml,
280 PypiPipOriginJson,
281 PypiEgg,
282 PypiEggPkginfo,
283 PypiEditableEggPkginfo,
284 PypiInspectDeplock,
285 PypiJson,
286 PypiPoetryLock,
287 PypiPoetryPyprojectToml,
288 PypiSdist,
289 PypiPylockToml,
290 PypiPyprojectToml,
291 PypiSdistPkginfo,
292 PypiSetupCfg,
293 PypiSetupPy,
294 PypiUvLock,
295 PypiWheel,
296 PypiWheelMetadata,
297
298 RpmArchive,
300 RpmInstalledDatabaseBdb,
301 RpmInstalledDatabaseNdb,
302 RpmInstalledDatabaseSqlite,
303 RpmMarinerManifest,
304 RpmPackageLicenses,
305 RpmSpecfile,
306 RpmYumdb,
307
308 Gemfile,
310 GemfileExtracted,
311 GemfileLock,
312 GemfileLockExtracted,
313 GemArchive,
314 GemArchiveExtracted,
316 Gemspec,
317 GemspecExtracted,
318 GemGemspecInstalledSpecifications,
319
320 InstallshieldInstaller,
322 IsoDiskImage,
323 NsisInstaller,
324 SharShellArchive,
325 SquashfsDiskImage,
326
327 SwiftPackageManifestJson,
329 SwiftPackageResolved,
330 SwiftPackageShowDependencies,
331
332 PubliccodeYaml,
333
334 VcpkgJson,
336
337 YarnLock,
339 YarnLockV1,
340 YarnLockV2,
341 YarnPnpCjs,
342
343 Gitmodules,
345}
346
347impl DatasourceId {
348 pub fn as_str(&self) -> &'static str {
352 match self {
353 Self::AboutFile => "about_file",
355 Self::Readme => "readme",
356 Self::EtcOsRelease => "etc_os_release",
357
358 Self::AlpineApkArchive => "alpine_apk_archive",
360 Self::AlpineApkbuild => "alpine_apkbuild",
361 Self::AlpineInstalledDb => "alpine_installed_db",
362
363 Self::ArchAurinfo => "arch_aurinfo",
365 Self::ArchPkginfo => "arch_pkginfo",
366 Self::ArchSrcinfo => "arch_srcinfo",
367
368 Self::AndroidAab => "android_aab",
370 Self::AndroidAarLibrary => "android_aar_library",
371 Self::AndroidApk => "android_apk",
372 Self::AndroidManifestXml => "android_manifest_xml",
373 Self::AndroidSoongMetadata => "android_soong_metadata",
374
375 Self::Axis2Mar => "axis2_mar",
377 Self::Axis2ModuleXml => "axis2_module_xml",
378
379 Self::AutotoolsConfigure => "autotools_configure",
381
382 Self::BazelBuild => "bazel_build",
384
385 Self::BitbakeRecipe => "bitbake_recipe",
387 Self::BitbakeRecipeAppend => "bitbake_recipe_append",
388
389 Self::BowerJson => "bower_json",
391
392 Self::BuckFile => "buck_file",
394 Self::BuckMetadata => "buck_metadata",
395
396 Self::CarthageCartfile => "carthage_cartfile",
398 Self::CarthageCartfileResolved => "carthage_cartfile_resolved",
399
400 Self::CargoLock => "cargo_lock",
402 Self::CargoToml => "cargo_toml",
403 Self::RustBinary => "rust_binary",
404 Self::WindowsExecutable => "windows_executable",
405
406 Self::ChefCookbookMetadataJson => "chef_cookbook_metadata_json",
408 Self::ChefCookbookMetadataRb => "chef_cookbook_metadata_rb",
409
410 Self::CitationCff => "citation_cff",
411
412 Self::CocoapodsPodfile => "cocoapods_podfile",
414 Self::CocoapodsPodfileLock => "cocoapods_podfile_lock",
415 Self::CocoapodsPodspec => "cocoapods_podspec",
416 Self::CocoapodsPodspecJson => "cocoapods_podspec_json",
417
418 Self::ConanConanDataYml => "conan_conandata_yml",
420 Self::ConanConanFilePy => "conan_conanfile_py",
421 Self::ConanConanFileTxt => "conan_conanfile_txt",
422 Self::ConanLock => "conan_lock",
423
424 Self::CondaYaml => "conda_yaml",
426 Self::CondaMetaJson => "conda_meta_json",
427 Self::CondaMetaYaml => "conda_meta_yaml",
428
429 Self::ClojureDepsEdn => "clojure_deps_edn",
431 Self::ClojureProjectClj => "clojure_project_clj",
432
433 Self::CpanDistIni => "cpan_dist_ini",
435 Self::CpanMakefile => "cpan_makefile",
436 Self::CpanManifest => "cpan_manifest",
437 Self::CpanMetaJson => "cpan_meta_json",
438 Self::CpanMetaYml => "cpan_meta_yml",
439
440 Self::CranDescription => "cran_description",
442
443 Self::PubspecLock => "pubspec_lock",
445 Self::PubspecYaml => "pubspec_yaml",
446
447 Self::DebianControlExtractedDeb => "debian_control_extracted_deb",
449 Self::DebianControlInSource => "debian_control_in_source",
450 Self::DebianCopyright => "debian_copyright",
451 Self::DebianCopyrightInSource => "debian_copyright_in_source",
452 Self::DebianCopyrightInPackage => "debian_copyright_in_package",
453 Self::DebianCopyrightStandalone => "debian_copyright_standalone",
454 Self::DebianDeb => "debian_deb",
455 Self::DebianSourceMetadataTarball => "debian_source_metadata_tarball",
456 Self::DebianDistrolessInstalledDb => "debian_distroless_installed_db",
457 Self::DebianInstalledFilesList => "debian_installed_files_list",
458 Self::DebianInstalledMd5Sums => "debian_installed_md5sums",
459 Self::DebianInstalledStatusDb => "debian_installed_status_db",
460 Self::DebianMd5SumsInExtractedDeb => "debian_md5sums_in_extracted_deb",
461 Self::DebianOriginalSourceTarball => "debian_original_source_tarball",
462 Self::DebianSourceControlDsc => "debian_source_control_dsc",
463 Self::DenoJson => "deno_json",
464 Self::DenoLock => "deno_lock",
465 Self::Dockerfile => "dockerfile",
466 Self::OciImageIndex => "oci_image_index",
467 Self::OciImageManifest => "oci_image_manifest",
468 Self::ErlangOtpAppSrc => "erlang_otp_app_src",
469 Self::RebarConfig => "rebar_config",
470 Self::RebarLock => "rebar_lock",
471 Self::BazelModule => "bazel_module",
472
473 Self::FreebsdCompactManifest => "freebsd_compact_manifest",
475
476 Self::Godeps => "godeps",
478 Self::GoBinary => "go_binary",
479 Self::GoMod => "go_mod",
480 Self::GoModGraph => "go_mod_graph",
481 Self::GoSum => "go_sum",
482 Self::GoWork => "go_work",
483
484 Self::HackageCabal => "hackage_cabal",
486 Self::HackageCabalProject => "hackage_cabal_project",
487 Self::HackageStackYaml => "hackage_stack_yaml",
488
489 Self::BuildGradle => "build_gradle",
491 Self::GradleLockfile => "gradle_lockfile",
492 Self::GradleModule => "gradle_module",
493
494 Self::HaxelibJson => "haxelib_json",
496
497 Self::HelmChartLock => "helm_chart_lock",
499 Self::HelmChartYaml => "helm_chart_yaml",
500
501 Self::HexMixLock => "hex_mix_lock",
503
504 Self::HuggingfaceModelCard => "huggingface_model_card",
506 Self::HuggingfaceConfigJson => "huggingface_config_json",
507 Self::HuggingfaceModelIndexJson => "huggingface_model_index_json",
508
509 Self::JuliaProjectToml => "julia_project_toml",
511 Self::JuliaManifestToml => "julia_manifest_toml",
512
513 Self::AntIvyXml => "ant_ivy_xml",
515 Self::JavaEarApplicationXml => "java_ear_application_xml",
516 Self::JavaEarArchive => "java_ear_archive",
517 Self::JavaJar => "java_jar",
518 Self::JavaJarManifest => "java_jar_manifest",
519 Self::JavaOsgiManifest => "java_osgi_manifest",
520 Self::JavaWarArchive => "java_war_archive",
521 Self::JavaWarWebXml => "java_war_web_xml",
522 Self::JbossSar => "jboss_sar",
523 Self::JbossServiceXml => "jboss_service_xml",
524
525 Self::MavenPom => "maven_pom",
527 Self::MavenPomProperties => "maven_pom_properties",
528 Self::MesonBuild => "meson_build",
529 Self::SbtBuildSbt => "sbt_build_sbt",
530
531 Self::MicrosoftCabinet => "microsoft_cabinet",
533 Self::MicrosoftUpdateManifestMum => "microsoft_update_manifest_mum",
534
535 Self::AppleDmg => "apple_dmg",
537 Self::ChromeCrx => "chrome_crx",
538 Self::IosIpa => "ios_ipa",
539 Self::MozillaXpi => "mozilla_xpi",
540
541 Self::MeteorPackage => "meteor_package",
543
544 Self::NixDefaultNix => "nix_default_nix",
545 Self::NixFlakeLock => "nix_flake_lock",
546 Self::NixFlakeNix => "nix_flake_nix",
547
548 Self::BunLock => "bun_lock",
550 Self::BunLockb => "bun_lockb",
551 Self::NpmPackageJson => "npm_package_json",
552 Self::NpmPackageLockJson => "npm_package_lock_json",
553
554 Self::NugetCsproj => "nuget_csproj",
556 Self::NugetDepsJson => "nuget_deps_json",
557 Self::NugetDirectoryBuildProps => "nuget_directory_build_props",
558 Self::NugetDirectoryPackagesProps => "nuget_directory_packages_props",
559 Self::NugetNupkg => "nuget_nupkg",
560 Self::NugetProjectJson => "nuget_project_json",
561 Self::NugetProjectLockJson => "nuget_project_lock_json",
562 Self::NugetPackagesConfig => "nuget_packages_config",
563 Self::NugetPackagesLock => "nuget_packages_lock",
564 Self::NugetNuspec => "nuget_nuspec",
565 Self::NugetVbproj => "nuget_vbproj",
566 Self::NugetFsproj => "nuget_fsproj",
567
568 Self::OpamFile => "opam_file",
570
571 Self::PhpComposerJson => "php_composer_json",
573 Self::PhpComposerLock => "php_composer_lock",
574
575 Self::PnpmLockYaml => "pnpm_lock_yaml",
577 Self::PnpmWorkspaceYaml => "pnpm_workspace_yaml",
578
579 Self::Pipfile => "pipfile",
581 Self::PipfileLock => "pipfile_lock",
582 Self::PipRequirements => "pip_requirements",
583 Self::PixiLock => "pixi_lock",
584 Self::PixiToml => "pixi_toml",
585 Self::PypiPipOriginJson => "pypi_pip_origin_json",
586 Self::PypiEgg => "pypi_egg",
587 Self::PypiEggPkginfo => "pypi_egg_pkginfo",
588 Self::PypiEditableEggPkginfo => "pypi_editable_egg_pkginfo",
589 Self::PypiInspectDeplock => "pypi_inspect_deplock",
590 Self::PypiJson => "pypi_json",
591 Self::PypiPoetryLock => "pypi_poetry_lock",
592 Self::PypiPoetryPyprojectToml => "pypi_poetry_pyproject_toml",
593 Self::PypiSdist => "pypi_sdist",
594 Self::PypiPylockToml => "pypi_pylock_toml",
595 Self::PypiPyprojectToml => "pypi_pyproject_toml",
596 Self::PypiSdistPkginfo => "pypi_sdist_pkginfo",
597 Self::PypiSetupCfg => "pypi_setup_cfg",
598 Self::PypiSetupPy => "pypi_setup_py",
599 Self::PypiUvLock => "pypi_uv_lock",
600 Self::PypiWheel => "pypi_wheel",
601 Self::PypiWheelMetadata => "pypi_wheel_metadata",
602
603 Self::RpmArchive => "rpm_archive",
605 Self::RpmInstalledDatabaseBdb => "rpm_installed_database_bdb",
606 Self::RpmInstalledDatabaseNdb => "rpm_installed_database_ndb",
607 Self::RpmInstalledDatabaseSqlite => "rpm_installed_database_sqlite",
608 Self::RpmMarinerManifest => "rpm_mariner_manifest",
609 Self::RpmPackageLicenses => "rpm_package_licenses",
610 Self::RpmSpecfile => "rpm_specfile",
611 Self::RpmYumdb => "rpm_yumdb",
612
613 Self::Gemfile => "gemfile",
615 Self::GemfileExtracted => "gemfile_extracted",
616 Self::GemfileLock => "gemfile_lock",
617 Self::GemfileLockExtracted => "gemfile_lock_extracted",
618 Self::GemArchive => "gem_archive",
619 Self::GemArchiveExtracted => "gem_archive_extracted",
620 Self::Gemspec => "gemspec",
621 Self::GemspecExtracted => "gemspec_extracted",
622 Self::GemGemspecInstalledSpecifications => "gem_gemspec_installed_specifications",
623
624 Self::InstallshieldInstaller => "installshield_installer",
626 Self::IsoDiskImage => "iso_disk_image",
627 Self::NsisInstaller => "nsis_installer",
628 Self::SharShellArchive => "shar_shell_archive",
629 Self::SquashfsDiskImage => "squashfs_disk_image",
630
631 Self::SwiftPackageManifestJson => "swift_package_manifest_json",
633 Self::SwiftPackageResolved => "swift_package_resolved",
634 Self::SwiftPackageShowDependencies => "swift_package_show_dependencies",
635
636 Self::PubliccodeYaml => "publiccode_yaml",
637
638 Self::VcpkgJson => "vcpkg_json",
640
641 Self::YarnLock => "yarn_lock",
643 Self::YarnLockV1 => "yarn_lock_v1",
644 Self::YarnLockV2 => "yarn_lock_v2",
645 Self::YarnPnpCjs => "yarn_pnp_cjs",
646
647 Self::Gitmodules => "gitmodules",
649 }
650 }
651}
652
653impl AsRef<str> for DatasourceId {
654 fn as_ref(&self) -> &str {
655 self.as_str()
656 }
657}
658
659impl fmt::Display for DatasourceId {
660 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
661 f.write_str(self.as_str())
662 }
663}
664
665impl FromStr for DatasourceId {
666 type Err = String;
667
668 fn from_str(s: &str) -> Result<Self, Self::Err> {
669 use strum::IntoEnumIterator;
670 Self::iter()
671 .find(|variant| variant.as_str() == s)
672 .ok_or_else(|| format!("unknown datasource id: {}", s))
673 }
674}
675
676#[cfg(test)]
677mod tests {
678 use super::*;
679
680 #[test]
681 fn test_serialization() {
682 let id = DatasourceId::NpmPackageJson;
683 let json = serde_json::to_string(&id).unwrap();
684 assert_eq!(json, r#""NpmPackageJson""#);
685 }
686
687 #[test]
688 fn test_deserialization() {
689 let json = r#""NpmPackageJson""#;
690 let id: DatasourceId = serde_json::from_str(json).unwrap();
691 assert_eq!(id, DatasourceId::NpmPackageJson);
692 }
693
694 #[test]
695 fn test_as_str() {
696 assert_eq!(DatasourceId::NpmPackageJson.as_str(), "npm_package_json");
697 assert_eq!(DatasourceId::CargoLock.as_str(), "cargo_lock");
698 assert_eq!(
699 DatasourceId::PypiPyprojectToml.as_str(),
700 "pypi_pyproject_toml"
701 );
702 assert_eq!(DatasourceId::HackageCabal.as_str(), "hackage_cabal");
703 assert_eq!(DatasourceId::CitationCff.as_str(), "citation_cff");
704 assert_eq!(DatasourceId::PubliccodeYaml.as_str(), "publiccode_yaml");
705 assert_eq!(DatasourceId::YarnPnpCjs.as_str(), "yarn_pnp_cjs");
706 }
707
708 #[test]
709 fn test_display() {
710 assert_eq!(DatasourceId::NpmPackageJson.to_string(), "npm_package_json");
711 }
712
713 #[test]
714 fn test_as_ref() {
715 let id = DatasourceId::NpmPackageJson;
716 let s: &str = id.as_ref();
717 assert_eq!(s, "npm_package_json");
718 }
719
720 #[test]
721 fn test_python_rename_mappings() {
722 assert_eq!(DatasourceId::BuckFile.as_str(), "buck_file");
724 assert_eq!(DatasourceId::BuckMetadata.as_str(), "buck_metadata");
725 assert_eq!(
726 DatasourceId::ChefCookbookMetadataJson.as_str(),
727 "chef_cookbook_metadata_json"
728 );
729 assert_eq!(
730 DatasourceId::ChefCookbookMetadataRb.as_str(),
731 "chef_cookbook_metadata_rb"
732 );
733 assert_eq!(DatasourceId::CondaYaml.as_str(), "conda_yaml");
734 assert_eq!(DatasourceId::CpanMakefile.as_str(), "cpan_makefile");
735 assert_eq!(
736 DatasourceId::DebianInstalledFilesList.as_str(),
737 "debian_installed_files_list"
738 );
739 assert_eq!(
740 DatasourceId::DebianOriginalSourceTarball.as_str(),
741 "debian_original_source_tarball"
742 );
743 assert_eq!(
744 DatasourceId::DebianSourceMetadataTarball.as_str(),
745 "debian_source_metadata_tarball"
746 );
747 assert_eq!(
748 DatasourceId::GemArchiveExtracted.as_str(),
749 "gem_archive_extracted"
750 );
751 assert_eq!(DatasourceId::NugetNuspec.as_str(), "nuget_nuspec");
753 assert_eq!(DatasourceId::RpmSpecfile.as_str(), "rpm_specfile");
754 }
755
756 #[test]
757 fn test_canonical_serialization() {
758 let nuget_json = serde_json::to_string(&DatasourceId::NugetNuspec).unwrap();
759 assert_eq!(nuget_json, r#""NugetNuspec""#);
760
761 let rpm_json = serde_json::to_string(&DatasourceId::RpmSpecfile).unwrap();
762 assert_eq!(rpm_json, r#""RpmSpecfile""#);
763 }
764
765 #[test]
766 fn test_from_str_uses_canonical_ids_and_rejects_legacy_typos() {
767 assert_eq!(
768 DatasourceId::from_str("nuget_nuspec").unwrap(),
769 DatasourceId::NugetNuspec
770 );
771 assert_eq!(
772 DatasourceId::from_str("rpm_specfile").unwrap(),
773 DatasourceId::RpmSpecfile
774 );
775 assert!(DatasourceId::from_str("nuget_nupsec").is_err());
779 assert!(DatasourceId::from_str("rpm_spefile").is_err());
780 }
781}