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