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
358 YarnLock,
360 YarnLockV1,
361 YarnLockV2,
362 YarnPnpCjs,
363
364 Gitmodules,
366}
367
368impl DatasourceId {
369 pub fn as_str(&self) -> &'static str {
373 match self {
374 Self::AboutFile => "about_file",
376 Self::Readme => "readme",
377 Self::EtcOsRelease => "etc_os_release",
378
379 Self::AlpineApkArchive => "alpine_apk_archive",
381 Self::AlpineApkbuild => "alpine_apkbuild",
382 Self::AlpineInstalledDb => "alpine_installed_db",
383
384 Self::ArchAurinfo => "arch_aurinfo",
386 Self::ArchPkginfo => "arch_pkginfo",
387 Self::ArchSrcinfo => "arch_srcinfo",
388
389 Self::AndroidAab => "android_aab",
391 Self::AndroidAarLibrary => "android_aar_library",
392 Self::AndroidApk => "android_apk",
393 Self::AndroidManifestXml => "android_manifest_xml",
394 Self::AndroidSoongMetadata => "android_soong_metadata",
395
396 Self::Axis2Mar => "axis2_mar",
398 Self::Axis2ModuleXml => "axis2_module_xml",
399
400 Self::AutotoolsConfigure => "autotools_configure",
402
403 Self::BazelBuild => "bazel_build",
405
406 Self::BitbakeRecipe => "bitbake_recipe",
408 Self::BitbakeRecipeAppend => "bitbake_recipe_append",
409
410 Self::BowerJson => "bower_json",
412
413 Self::BuckFile => "buck_file",
415 Self::BuckMetadata => "buck_metadata",
416
417 Self::CarthageCartfile => "carthage_cartfile",
419 Self::CarthageCartfileResolved => "carthage_cartfile_resolved",
420
421 Self::CargoLock => "cargo_lock",
423 Self::CargoToml => "cargo_toml",
424 Self::RustBinary => "rust_binary",
425 Self::WindowsExecutable => "windows_executable",
426
427 Self::ChefCookbookMetadataJson => "chef_cookbook_metadata_json",
429 Self::ChefCookbookMetadataRb => "chef_cookbook_metadata_rb",
430
431 Self::CitationCff => "citation_cff",
432
433 Self::CocoapodsPodfile => "cocoapods_podfile",
435 Self::CocoapodsPodfileLock => "cocoapods_podfile_lock",
436 Self::CocoapodsPodspec => "cocoapods_podspec",
437 Self::CocoapodsPodspecJson => "cocoapods_podspec_json",
438
439 Self::ConanConanDataYml => "conan_conandata_yml",
441 Self::ConanConanFilePy => "conan_conanfile_py",
442 Self::ConanConanFileTxt => "conan_conanfile_txt",
443 Self::ConanLock => "conan_lock",
444
445 Self::CondaYaml => "conda_yaml",
447 Self::CondaMetaJson => "conda_meta_json",
448 Self::CondaMetaYaml => "conda_meta_yaml",
449
450 Self::ClojureDepsEdn => "clojure_deps_edn",
452 Self::ClojureProjectClj => "clojure_project_clj",
453
454 Self::CpanDistIni => "cpan_dist_ini",
456 Self::CpanMakefile => "cpan_makefile",
457 Self::CpanManifest => "cpan_manifest",
458 Self::CpanMetaJson => "cpan_meta_json",
459 Self::CpanMetaYml => "cpan_meta_yml",
460
461 Self::CranDescription => "cran_description",
463
464 Self::PubspecLock => "pubspec_lock",
466 Self::PubspecYaml => "pubspec_yaml",
467
468 Self::DebianControlExtractedDeb => "debian_control_extracted_deb",
470 Self::DebianControlInSource => "debian_control_in_source",
471 Self::DebianCopyright => "debian_copyright",
472 Self::DebianCopyrightInSource => "debian_copyright_in_source",
473 Self::DebianCopyrightInPackage => "debian_copyright_in_package",
474 Self::DebianCopyrightStandalone => "debian_copyright_standalone",
475 Self::DebianDeb => "debian_deb",
476 Self::DebianSourceMetadataTarball => "debian_source_metadata_tarball",
477 Self::DebianDistrolessInstalledDb => "debian_distroless_installed_db",
478 Self::DebianInstalledFilesList => "debian_installed_files_list",
479 Self::DebianInstalledMd5Sums => "debian_installed_md5sums",
480 Self::DebianInstalledStatusDb => "debian_installed_status_db",
481 Self::DebianMd5SumsInExtractedDeb => "debian_md5sums_in_extracted_deb",
482 Self::DebianOriginalSourceTarball => "debian_original_source_tarball",
483 Self::DebianSourceControlDsc => "debian_source_control_dsc",
484 Self::DenoJson => "deno_json",
485 Self::DenoLock => "deno_lock",
486 Self::Dockerfile => "dockerfile",
487 Self::OciImageIndex => "oci_image_index",
488 Self::OciImageManifest => "oci_image_manifest",
489 Self::ErlangOtpAppSrc => "erlang_otp_app_src",
490 Self::RebarConfig => "rebar_config",
491 Self::RebarLock => "rebar_lock",
492 Self::BazelModule => "bazel_module",
493
494 Self::FreebsdCompactManifest => "freebsd_compact_manifest",
496
497 Self::Godeps => "godeps",
499 Self::GoBinary => "go_binary",
500 Self::GoMod => "go_mod",
501 Self::GoModGraph => "go_mod_graph",
502 Self::GoSum => "go_sum",
503 Self::GoWork => "go_work",
504
505 Self::HackageCabal => "hackage_cabal",
507 Self::HackageCabalProject => "hackage_cabal_project",
508 Self::HackageStackYaml => "hackage_stack_yaml",
509
510 Self::BuildGradle => "build_gradle",
512 Self::GradleLockfile => "gradle_lockfile",
513 Self::GradleModule => "gradle_module",
514
515 Self::HaxelibJson => "haxelib_json",
517
518 Self::HelmChartLock => "helm_chart_lock",
520 Self::HelmChartYaml => "helm_chart_yaml",
521
522 Self::HexMixLock => "hex_mix_lock",
524
525 Self::HuggingfaceModelCard => "huggingface_model_card",
527 Self::HuggingfaceConfigJson => "huggingface_config_json",
528 Self::HuggingfaceModelIndexJson => "huggingface_model_index_json",
529
530 Self::JuliaProjectToml => "julia_project_toml",
532 Self::JuliaManifestToml => "julia_manifest_toml",
533
534 Self::AntIvyXml => "ant_ivy_xml",
536 Self::JavaEarApplicationXml => "java_ear_application_xml",
537 Self::JavaEarArchive => "java_ear_archive",
538 Self::JavaJar => "java_jar",
539 Self::JavaJarManifest => "java_jar_manifest",
540 Self::JavaOsgiManifest => "java_osgi_manifest",
541 Self::JavaWarArchive => "java_war_archive",
542 Self::JavaWarWebXml => "java_war_web_xml",
543 Self::JbossSar => "jboss_sar",
544 Self::JbossServiceXml => "jboss_service_xml",
545
546 Self::MavenPom => "maven_pom",
548 Self::MavenPomProperties => "maven_pom_properties",
549 Self::MesonBuild => "meson_build",
550 Self::SbtBuildSbt => "sbt_build_sbt",
551
552 Self::MicrosoftCabinet => "microsoft_cabinet",
554 Self::MicrosoftUpdateManifestMum => "microsoft_update_manifest_mum",
555
556 Self::AppleDmg => "apple_dmg",
558 Self::ChromeCrx => "chrome_crx",
559 Self::IosIpa => "ios_ipa",
560 Self::MozillaXpi => "mozilla_xpi",
561
562 Self::MeteorPackage => "meteor_package",
564
565 Self::NixDefaultNix => "nix_default_nix",
566 Self::NixFlakeLock => "nix_flake_lock",
567 Self::NixFlakeNix => "nix_flake_nix",
568
569 Self::BunLock => "bun_lock",
571 Self::BunLockb => "bun_lockb",
572 Self::NpmPackageJson => "npm_package_json",
573 Self::NpmPackageLockJson => "npm_package_lock_json",
574
575 Self::NugetCsproj => "nuget_csproj",
577 Self::NugetDepsJson => "nuget_deps_json",
578 Self::NugetDirectoryBuildProps => "nuget_directory_build_props",
579 Self::NugetDirectoryPackagesProps => "nuget_directory_packages_props",
580 Self::NugetNupkg => "nuget_nupkg",
581 Self::NugetProjectJson => "nuget_project_json",
582 Self::NugetProjectLockJson => "nuget_project_lock_json",
583 Self::NugetPackagesConfig => "nuget_packages_config",
584 Self::NugetPackagesLock => "nuget_packages_lock",
585 Self::NugetNuspec => "nuget_nuspec",
586 Self::NugetVbproj => "nuget_vbproj",
587 Self::NugetFsproj => "nuget_fsproj",
588
589 Self::OpamFile => "opam_file",
591
592 Self::PhpComposerJson => "php_composer_json",
594 Self::PhpComposerLock => "php_composer_lock",
595
596 Self::PnpmLockYaml => "pnpm_lock_yaml",
598 Self::PnpmWorkspaceYaml => "pnpm_workspace_yaml",
599
600 Self::Pipfile => "pipfile",
602 Self::PipfileLock => "pipfile_lock",
603 Self::PipRequirements => "pip_requirements",
604 Self::PixiLock => "pixi_lock",
605 Self::PixiToml => "pixi_toml",
606 Self::PypiPipOriginJson => "pypi_pip_origin_json",
607 Self::PypiEgg => "pypi_egg",
608 Self::PypiEggPkginfo => "pypi_egg_pkginfo",
609 Self::PypiEditableEggPkginfo => "pypi_editable_egg_pkginfo",
610 Self::PypiInspectDeplock => "pypi_inspect_deplock",
611 Self::PypiJson => "pypi_json",
612 Self::PypiPoetryLock => "pypi_poetry_lock",
613 Self::PypiPoetryPyprojectToml => "pypi_poetry_pyproject_toml",
614 Self::PypiSdist => "pypi_sdist",
615 Self::PypiPylockToml => "pypi_pylock_toml",
616 Self::PypiPyprojectToml => "pypi_pyproject_toml",
617 Self::PypiSdistPkginfo => "pypi_sdist_pkginfo",
618 Self::PypiSetupCfg => "pypi_setup_cfg",
619 Self::PypiSetupPy => "pypi_setup_py",
620 Self::PypiUvLock => "pypi_uv_lock",
621 Self::PypiWheel => "pypi_wheel",
622 Self::PypiWheelMetadata => "pypi_wheel_metadata",
623
624 Self::RpmArchive => "rpm_archive",
626 Self::RpmInstalledDatabaseBdb => "rpm_installed_database_bdb",
627 Self::RpmInstalledDatabaseNdb => "rpm_installed_database_ndb",
628 Self::RpmInstalledDatabaseSqlite => "rpm_installed_database_sqlite",
629 Self::RpmMarinerManifest => "rpm_mariner_manifest",
630 Self::RpmPackageLicenses => "rpm_package_licenses",
631 Self::RpmSpecfile => "rpm_specfile",
632 Self::RpmYumdb => "rpm_yumdb",
633
634 Self::Gemfile => "gemfile",
636 Self::GemfileExtracted => "gemfile_extracted",
637 Self::GemfileLock => "gemfile_lock",
638 Self::GemfileLockExtracted => "gemfile_lock_extracted",
639 Self::GemArchive => "gem_archive",
640 Self::GemArchiveExtracted => "gem_archive_extracted",
641 Self::Gemspec => "gemspec",
642 Self::GemspecExtracted => "gemspec_extracted",
643 Self::GemGemspecInstalledSpecifications => "gem_gemspec_installed_specifications",
644
645 Self::InstallshieldInstaller => "installshield_installer",
647 Self::IsoDiskImage => "iso_disk_image",
648 Self::NsisInstaller => "nsis_installer",
649 Self::SharShellArchive => "shar_shell_archive",
650 Self::SquashfsDiskImage => "squashfs_disk_image",
651
652 Self::SwiftPackageManifestJson => "swift_package_manifest_json",
654 Self::SwiftPackageResolved => "swift_package_resolved",
655 Self::SwiftPackageShowDependencies => "swift_package_show_dependencies",
656
657 Self::PubliccodeYaml => "publiccode_yaml",
658
659 Self::VcpkgJson => "vcpkg_json",
661
662 Self::YarnLock => "yarn_lock",
664 Self::YarnLockV1 => "yarn_lock_v1",
665 Self::YarnLockV2 => "yarn_lock_v2",
666 Self::YarnPnpCjs => "yarn_pnp_cjs",
667
668 Self::Gitmodules => "gitmodules",
670 }
671 }
672}
673
674impl AsRef<str> for DatasourceId {
675 fn as_ref(&self) -> &str {
676 self.as_str()
677 }
678}
679
680impl fmt::Display for DatasourceId {
681 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
682 f.write_str(self.as_str())
683 }
684}
685
686impl FromStr for DatasourceId {
687 type Err = String;
688
689 fn from_str(s: &str) -> Result<Self, Self::Err> {
690 use strum::IntoEnumIterator;
691 Self::iter()
692 .find(|variant| variant.as_str() == s)
693 .ok_or_else(|| format!("unknown datasource id: {}", s))
694 }
695}
696
697#[cfg(test)]
698mod tests {
699 use super::*;
700
701 #[test]
702 fn test_serialization() {
703 let id = DatasourceId::NpmPackageJson;
704 let json = serde_json::to_string(&id).unwrap();
705 assert_eq!(json, r#""NpmPackageJson""#);
706 }
707
708 #[test]
709 fn test_deserialization() {
710 let json = r#""NpmPackageJson""#;
711 let id: DatasourceId = serde_json::from_str(json).unwrap();
712 assert_eq!(id, DatasourceId::NpmPackageJson);
713 }
714
715 #[test]
716 fn test_as_str() {
717 assert_eq!(DatasourceId::NpmPackageJson.as_str(), "npm_package_json");
718 assert_eq!(DatasourceId::CargoLock.as_str(), "cargo_lock");
719 assert_eq!(
720 DatasourceId::PypiPyprojectToml.as_str(),
721 "pypi_pyproject_toml"
722 );
723 assert_eq!(DatasourceId::HackageCabal.as_str(), "hackage_cabal");
724 assert_eq!(DatasourceId::CitationCff.as_str(), "citation_cff");
725 assert_eq!(DatasourceId::PubliccodeYaml.as_str(), "publiccode_yaml");
726 assert_eq!(DatasourceId::YarnPnpCjs.as_str(), "yarn_pnp_cjs");
727 }
728
729 #[test]
730 fn test_display() {
731 assert_eq!(DatasourceId::NpmPackageJson.to_string(), "npm_package_json");
732 }
733
734 #[test]
735 fn test_as_ref() {
736 let id = DatasourceId::NpmPackageJson;
737 let s: &str = id.as_ref();
738 assert_eq!(s, "npm_package_json");
739 }
740
741 #[test]
742 fn test_python_rename_mappings() {
743 assert_eq!(DatasourceId::BuckFile.as_str(), "buck_file");
745 assert_eq!(DatasourceId::BuckMetadata.as_str(), "buck_metadata");
746 assert_eq!(
747 DatasourceId::ChefCookbookMetadataJson.as_str(),
748 "chef_cookbook_metadata_json"
749 );
750 assert_eq!(
751 DatasourceId::ChefCookbookMetadataRb.as_str(),
752 "chef_cookbook_metadata_rb"
753 );
754 assert_eq!(DatasourceId::CondaYaml.as_str(), "conda_yaml");
755 assert_eq!(DatasourceId::CpanMakefile.as_str(), "cpan_makefile");
756 assert_eq!(
757 DatasourceId::DebianInstalledFilesList.as_str(),
758 "debian_installed_files_list"
759 );
760 assert_eq!(
761 DatasourceId::DebianOriginalSourceTarball.as_str(),
762 "debian_original_source_tarball"
763 );
764 assert_eq!(
765 DatasourceId::DebianSourceMetadataTarball.as_str(),
766 "debian_source_metadata_tarball"
767 );
768 assert_eq!(
769 DatasourceId::GemArchiveExtracted.as_str(),
770 "gem_archive_extracted"
771 );
772 assert_eq!(DatasourceId::NugetNuspec.as_str(), "nuget_nuspec");
774 assert_eq!(DatasourceId::RpmSpecfile.as_str(), "rpm_specfile");
775 }
776
777 #[test]
778 fn test_canonical_serialization() {
779 let nuget_json = serde_json::to_string(&DatasourceId::NugetNuspec).unwrap();
780 assert_eq!(nuget_json, r#""NugetNuspec""#);
781
782 let rpm_json = serde_json::to_string(&DatasourceId::RpmSpecfile).unwrap();
783 assert_eq!(rpm_json, r#""RpmSpecfile""#);
784 }
785
786 #[test]
787 fn test_from_str_uses_canonical_ids_and_rejects_legacy_typos() {
788 assert_eq!(
789 DatasourceId::from_str("nuget_nuspec").unwrap(),
790 DatasourceId::NugetNuspec
791 );
792 assert_eq!(
793 DatasourceId::from_str("rpm_specfile").unwrap(),
794 DatasourceId::RpmSpecfile
795 );
796 assert!(DatasourceId::from_str("nuget_nupsec").is_err());
800 assert!(DatasourceId::from_str("rpm_spefile").is_err());
801 }
802}