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