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 AntIvyDependenciesProperties,
232 AntIvyXml,
233 JavaEarApplicationXml,
234 JavaEarArchive,
235 JavaJar,
236 JavaJarManifest,
237 JavaOsgiManifest,
238 JavaWarArchive,
239 JavaWarWebXml,
240 JbossSar,
241 JbossServiceXml,
242
243 MavenPom,
245 MavenPomProperties,
246 MesonBuild,
247
248 SbtBuildSbt,
249
250 MicrosoftCabinet,
252 MicrosoftUpdateManifestMum,
253
254 AppleDmg,
256 ChromeCrx,
257 IosIpa,
258 MozillaXpi,
259
260 MeteorPackage,
262
263 NixDefaultNix,
264 NixFlakeLock,
265 NixFlakeNix,
266
267 NpmPackageJson,
269 NpmPackageLockJson,
270
271 NugetCsproj,
273 NugetDepsJson,
274 NugetDirectoryBuildProps,
275 NugetDirectoryPackagesProps,
276 NugetNupkg,
277 NugetProjectJson,
278 NugetProjectLockJson,
279 NugetPackagesConfig,
280 NugetPackagesLock,
281 NugetNuspec,
282 NugetVbproj,
283 NugetFsproj,
284
285 OpamFile,
287
288 PhpComposerJson,
290 PhpComposerLock,
291
292 PnpmLockYaml,
294 PnpmWorkspaceYaml,
295
296 Pipfile,
298 PipfileLock,
299 PipRequirements,
300 PixiLock,
301 PixiToml,
302 PypiPipOriginJson,
303 PypiEgg,
304 PypiEggPkginfo,
305 PypiEditableEggPkginfo,
306 PypiInspectDeplock,
307 PypiJson,
308 PypiPoetryLock,
309 PypiPoetryPyprojectToml,
310 PypiSdist,
311 PypiPylockToml,
312 PypiPyprojectToml,
313 PypiSdistPkginfo,
314 PypiSetupCfg,
315 PypiSetupPy,
316 PypiUvLock,
317 PypiWheel,
318 PypiWheelMetadata,
319
320 RpmArchive,
322 RpmInstalledDatabaseBdb,
323 RpmInstalledDatabaseNdb,
324 RpmInstalledDatabaseSqlite,
325 RpmMarinerManifest,
326 RpmPackageLicenses,
327 RpmSpecfile,
328 RpmYumdb,
329
330 Gemfile,
332 GemfileExtracted,
333 GemfileLock,
334 GemfileLockExtracted,
335 GemArchive,
336 GemArchiveExtracted,
338 Gemspec,
339 GemspecExtracted,
340 GemGemspecInstalledSpecifications,
341
342 InstallshieldInstaller,
344 IsoDiskImage,
345 NsisInstaller,
346 SharShellArchive,
347 SquashfsDiskImage,
348
349 SwiftPackageManifestJson,
351 SwiftPackageResolved,
352 SwiftPackageShowDependencies,
353
354 PubliccodeYaml,
355
356 VcpkgJson,
358 VcpkgConfigurationJson,
359 VcpkgLockJson,
360 VcpkgControl,
361
362 YarnLock,
364 YarnLockV1,
365 YarnLockV2,
366 YarnPnpCjs,
367
368 Gitmodules,
370}
371
372impl DatasourceId {
373 pub fn as_str(&self) -> &'static str {
377 match self {
378 Self::AboutFile => "about_file",
380 Self::Readme => "readme",
381 Self::EtcOsRelease => "etc_os_release",
382
383 Self::AlpineApkArchive => "alpine_apk_archive",
385 Self::AlpineApkbuild => "alpine_apkbuild",
386 Self::AlpineInstalledDb => "alpine_installed_db",
387
388 Self::ArchAurinfo => "arch_aurinfo",
390 Self::ArchPkginfo => "arch_pkginfo",
391 Self::ArchSrcinfo => "arch_srcinfo",
392
393 Self::AndroidAab => "android_aab",
395 Self::AndroidAarLibrary => "android_aar_library",
396 Self::AndroidApk => "android_apk",
397 Self::AndroidManifestXml => "android_manifest_xml",
398 Self::AndroidSoongMetadata => "android_soong_metadata",
399
400 Self::Axis2Mar => "axis2_mar",
402 Self::Axis2ModuleXml => "axis2_module_xml",
403
404 Self::AutotoolsConfigure => "autotools_configure",
406
407 Self::BazelBuild => "bazel_build",
409
410 Self::BitbakeRecipe => "bitbake_recipe",
412 Self::BitbakeRecipeAppend => "bitbake_recipe_append",
413
414 Self::BowerJson => "bower_json",
416
417 Self::BuckFile => "buck_file",
419 Self::BuckMetadata => "buck_metadata",
420
421 Self::CarthageCartfile => "carthage_cartfile",
423 Self::CarthageCartfileResolved => "carthage_cartfile_resolved",
424
425 Self::CargoLock => "cargo_lock",
427 Self::CargoToml => "cargo_toml",
428 Self::RustBinary => "rust_binary",
429 Self::WindowsExecutable => "windows_executable",
430
431 Self::ChefCookbookMetadataJson => "chef_cookbook_metadata_json",
433 Self::ChefCookbookMetadataRb => "chef_cookbook_metadata_rb",
434
435 Self::CitationCff => "citation_cff",
436
437 Self::CocoapodsPodfile => "cocoapods_podfile",
439 Self::CocoapodsPodfileLock => "cocoapods_podfile_lock",
440 Self::CocoapodsPodspec => "cocoapods_podspec",
441 Self::CocoapodsPodspecJson => "cocoapods_podspec_json",
442
443 Self::ConanConanDataYml => "conan_conandata_yml",
445 Self::ConanConanFilePy => "conan_conanfile_py",
446 Self::ConanConanFileTxt => "conan_conanfile_txt",
447 Self::ConanLock => "conan_lock",
448
449 Self::CondaYaml => "conda_yaml",
451 Self::CondaMetaJson => "conda_meta_json",
452 Self::CondaMetaYaml => "conda_meta_yaml",
453
454 Self::ClojureDepsEdn => "clojure_deps_edn",
456 Self::ClojureProjectClj => "clojure_project_clj",
457
458 Self::CpanDistIni => "cpan_dist_ini",
460 Self::CpanMakefile => "cpan_makefile",
461 Self::CpanManifest => "cpan_manifest",
462 Self::CpanMetaJson => "cpan_meta_json",
463 Self::CpanMetaYml => "cpan_meta_yml",
464
465 Self::CranDescription => "cran_description",
467
468 Self::PubspecLock => "pubspec_lock",
470 Self::PubspecYaml => "pubspec_yaml",
471
472 Self::DebianControlExtractedDeb => "debian_control_extracted_deb",
474 Self::DebianControlInSource => "debian_control_in_source",
475 Self::DebianCopyright => "debian_copyright",
476 Self::DebianCopyrightInSource => "debian_copyright_in_source",
477 Self::DebianCopyrightInPackage => "debian_copyright_in_package",
478 Self::DebianCopyrightStandalone => "debian_copyright_standalone",
479 Self::DebianDeb => "debian_deb",
480 Self::DebianSourceMetadataTarball => "debian_source_metadata_tarball",
481 Self::DebianDistrolessInstalledDb => "debian_distroless_installed_db",
482 Self::DebianInstalledFilesList => "debian_installed_files_list",
483 Self::DebianInstalledMd5Sums => "debian_installed_md5sums",
484 Self::DebianInstalledStatusDb => "debian_installed_status_db",
485 Self::DebianMd5SumsInExtractedDeb => "debian_md5sums_in_extracted_deb",
486 Self::DebianOriginalSourceTarball => "debian_original_source_tarball",
487 Self::DebianSourceControlDsc => "debian_source_control_dsc",
488 Self::DenoJson => "deno_json",
489 Self::DenoLock => "deno_lock",
490 Self::Dockerfile => "dockerfile",
491 Self::OciImageIndex => "oci_image_index",
492 Self::OciImageManifest => "oci_image_manifest",
493 Self::ErlangOtpAppSrc => "erlang_otp_app_src",
494 Self::RebarConfig => "rebar_config",
495 Self::RebarLock => "rebar_lock",
496 Self::BazelModule => "bazel_module",
497
498 Self::FreebsdCompactManifest => "freebsd_compact_manifest",
500
501 Self::Godeps => "godeps",
503 Self::GoBinary => "go_binary",
504 Self::GoMod => "go_mod",
505 Self::GoModGraph => "go_mod_graph",
506 Self::GoSum => "go_sum",
507 Self::GoWork => "go_work",
508
509 Self::HackageCabal => "hackage_cabal",
511 Self::HackageCabalProject => "hackage_cabal_project",
512 Self::HackageStackYaml => "hackage_stack_yaml",
513
514 Self::BuildGradle => "build_gradle",
516 Self::GradleLockfile => "gradle_lockfile",
517 Self::GradleModule => "gradle_module",
518
519 Self::HaxelibJson => "haxelib_json",
521
522 Self::HelmChartLock => "helm_chart_lock",
524 Self::HelmChartYaml => "helm_chart_yaml",
525
526 Self::HexMixLock => "hex_mix_lock",
528
529 Self::HuggingfaceModelCard => "huggingface_model_card",
531 Self::HuggingfaceConfigJson => "huggingface_config_json",
532 Self::HuggingfaceModelIndexJson => "huggingface_model_index_json",
533
534 Self::JuliaProjectToml => "julia_project_toml",
536 Self::JuliaManifestToml => "julia_manifest_toml",
537
538 Self::AntIvyDependenciesProperties => "ant_ivy_dependencies_properties",
540 Self::AntIvyXml => "ant_ivy_xml",
541 Self::JavaEarApplicationXml => "java_ear_application_xml",
542 Self::JavaEarArchive => "java_ear_archive",
543 Self::JavaJar => "java_jar",
544 Self::JavaJarManifest => "java_jar_manifest",
545 Self::JavaOsgiManifest => "java_osgi_manifest",
546 Self::JavaWarArchive => "java_war_archive",
547 Self::JavaWarWebXml => "java_war_web_xml",
548 Self::JbossSar => "jboss_sar",
549 Self::JbossServiceXml => "jboss_service_xml",
550
551 Self::MavenPom => "maven_pom",
553 Self::MavenPomProperties => "maven_pom_properties",
554 Self::MesonBuild => "meson_build",
555 Self::SbtBuildSbt => "sbt_build_sbt",
556
557 Self::MicrosoftCabinet => "microsoft_cabinet",
559 Self::MicrosoftUpdateManifestMum => "microsoft_update_manifest_mum",
560
561 Self::AppleDmg => "apple_dmg",
563 Self::ChromeCrx => "chrome_crx",
564 Self::IosIpa => "ios_ipa",
565 Self::MozillaXpi => "mozilla_xpi",
566
567 Self::MeteorPackage => "meteor_package",
569
570 Self::NixDefaultNix => "nix_default_nix",
571 Self::NixFlakeLock => "nix_flake_lock",
572 Self::NixFlakeNix => "nix_flake_nix",
573
574 Self::BunLock => "bun_lock",
576 Self::BunLockb => "bun_lockb",
577 Self::NpmPackageJson => "npm_package_json",
578 Self::NpmPackageLockJson => "npm_package_lock_json",
579
580 Self::NugetCsproj => "nuget_csproj",
582 Self::NugetDepsJson => "nuget_deps_json",
583 Self::NugetDirectoryBuildProps => "nuget_directory_build_props",
584 Self::NugetDirectoryPackagesProps => "nuget_directory_packages_props",
585 Self::NugetNupkg => "nuget_nupkg",
586 Self::NugetProjectJson => "nuget_project_json",
587 Self::NugetProjectLockJson => "nuget_project_lock_json",
588 Self::NugetPackagesConfig => "nuget_packages_config",
589 Self::NugetPackagesLock => "nuget_packages_lock",
590 Self::NugetNuspec => "nuget_nuspec",
591 Self::NugetVbproj => "nuget_vbproj",
592 Self::NugetFsproj => "nuget_fsproj",
593
594 Self::OpamFile => "opam_file",
596
597 Self::PhpComposerJson => "php_composer_json",
599 Self::PhpComposerLock => "php_composer_lock",
600
601 Self::PnpmLockYaml => "pnpm_lock_yaml",
603 Self::PnpmWorkspaceYaml => "pnpm_workspace_yaml",
604
605 Self::Pipfile => "pipfile",
607 Self::PipfileLock => "pipfile_lock",
608 Self::PipRequirements => "pip_requirements",
609 Self::PixiLock => "pixi_lock",
610 Self::PixiToml => "pixi_toml",
611 Self::PypiPipOriginJson => "pypi_pip_origin_json",
612 Self::PypiEgg => "pypi_egg",
613 Self::PypiEggPkginfo => "pypi_egg_pkginfo",
614 Self::PypiEditableEggPkginfo => "pypi_editable_egg_pkginfo",
615 Self::PypiInspectDeplock => "pypi_inspect_deplock",
616 Self::PypiJson => "pypi_json",
617 Self::PypiPoetryLock => "pypi_poetry_lock",
618 Self::PypiPoetryPyprojectToml => "pypi_poetry_pyproject_toml",
619 Self::PypiSdist => "pypi_sdist",
620 Self::PypiPylockToml => "pypi_pylock_toml",
621 Self::PypiPyprojectToml => "pypi_pyproject_toml",
622 Self::PypiSdistPkginfo => "pypi_sdist_pkginfo",
623 Self::PypiSetupCfg => "pypi_setup_cfg",
624 Self::PypiSetupPy => "pypi_setup_py",
625 Self::PypiUvLock => "pypi_uv_lock",
626 Self::PypiWheel => "pypi_wheel",
627 Self::PypiWheelMetadata => "pypi_wheel_metadata",
628
629 Self::RpmArchive => "rpm_archive",
631 Self::RpmInstalledDatabaseBdb => "rpm_installed_database_bdb",
632 Self::RpmInstalledDatabaseNdb => "rpm_installed_database_ndb",
633 Self::RpmInstalledDatabaseSqlite => "rpm_installed_database_sqlite",
634 Self::RpmMarinerManifest => "rpm_mariner_manifest",
635 Self::RpmPackageLicenses => "rpm_package_licenses",
636 Self::RpmSpecfile => "rpm_specfile",
637 Self::RpmYumdb => "rpm_yumdb",
638
639 Self::Gemfile => "gemfile",
641 Self::GemfileExtracted => "gemfile_extracted",
642 Self::GemfileLock => "gemfile_lock",
643 Self::GemfileLockExtracted => "gemfile_lock_extracted",
644 Self::GemArchive => "gem_archive",
645 Self::GemArchiveExtracted => "gem_archive_extracted",
646 Self::Gemspec => "gemspec",
647 Self::GemspecExtracted => "gemspec_extracted",
648 Self::GemGemspecInstalledSpecifications => "gem_gemspec_installed_specifications",
649
650 Self::InstallshieldInstaller => "installshield_installer",
652 Self::IsoDiskImage => "iso_disk_image",
653 Self::NsisInstaller => "nsis_installer",
654 Self::SharShellArchive => "shar_shell_archive",
655 Self::SquashfsDiskImage => "squashfs_disk_image",
656
657 Self::SwiftPackageManifestJson => "swift_package_manifest_json",
659 Self::SwiftPackageResolved => "swift_package_resolved",
660 Self::SwiftPackageShowDependencies => "swift_package_show_dependencies",
661
662 Self::PubliccodeYaml => "publiccode_yaml",
663
664 Self::VcpkgJson => "vcpkg_json",
666 Self::VcpkgConfigurationJson => "vcpkg_configuration_json",
667 Self::VcpkgLockJson => "vcpkg_lock_json",
668 Self::VcpkgControl => "vcpkg_control",
669
670 Self::YarnLock => "yarn_lock",
672 Self::YarnLockV1 => "yarn_lock_v1",
673 Self::YarnLockV2 => "yarn_lock_v2",
674 Self::YarnPnpCjs => "yarn_pnp_cjs",
675
676 Self::Gitmodules => "gitmodules",
678 }
679 }
680}
681
682impl AsRef<str> for DatasourceId {
683 fn as_ref(&self) -> &str {
684 self.as_str()
685 }
686}
687
688impl fmt::Display for DatasourceId {
689 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
690 f.write_str(self.as_str())
691 }
692}
693
694impl FromStr for DatasourceId {
695 type Err = String;
696
697 fn from_str(s: &str) -> Result<Self, Self::Err> {
698 use strum::IntoEnumIterator;
699 Self::iter()
700 .find(|variant| variant.as_str() == s)
701 .ok_or_else(|| format!("unknown datasource id: {}", s))
702 }
703}
704
705#[cfg(test)]
706mod tests {
707 use super::*;
708
709 #[test]
710 fn test_serialization() {
711 let id = DatasourceId::NpmPackageJson;
712 let json = serde_json::to_string(&id).unwrap();
713 assert_eq!(json, r#""NpmPackageJson""#);
714 }
715
716 #[test]
717 fn test_deserialization() {
718 let json = r#""NpmPackageJson""#;
719 let id: DatasourceId = serde_json::from_str(json).unwrap();
720 assert_eq!(id, DatasourceId::NpmPackageJson);
721 }
722
723 #[test]
724 fn test_as_str() {
725 assert_eq!(DatasourceId::NpmPackageJson.as_str(), "npm_package_json");
726 assert_eq!(DatasourceId::CargoLock.as_str(), "cargo_lock");
727 assert_eq!(
728 DatasourceId::PypiPyprojectToml.as_str(),
729 "pypi_pyproject_toml"
730 );
731 assert_eq!(DatasourceId::HackageCabal.as_str(), "hackage_cabal");
732 assert_eq!(DatasourceId::CitationCff.as_str(), "citation_cff");
733 assert_eq!(DatasourceId::PubliccodeYaml.as_str(), "publiccode_yaml");
734 assert_eq!(DatasourceId::YarnPnpCjs.as_str(), "yarn_pnp_cjs");
735 }
736
737 #[test]
738 fn test_display() {
739 assert_eq!(DatasourceId::NpmPackageJson.to_string(), "npm_package_json");
740 }
741
742 #[test]
743 fn test_as_ref() {
744 let id = DatasourceId::NpmPackageJson;
745 let s: &str = id.as_ref();
746 assert_eq!(s, "npm_package_json");
747 }
748
749 #[test]
750 fn test_python_rename_mappings() {
751 assert_eq!(DatasourceId::BuckFile.as_str(), "buck_file");
753 assert_eq!(DatasourceId::BuckMetadata.as_str(), "buck_metadata");
754 assert_eq!(
755 DatasourceId::ChefCookbookMetadataJson.as_str(),
756 "chef_cookbook_metadata_json"
757 );
758 assert_eq!(
759 DatasourceId::ChefCookbookMetadataRb.as_str(),
760 "chef_cookbook_metadata_rb"
761 );
762 assert_eq!(DatasourceId::CondaYaml.as_str(), "conda_yaml");
763 assert_eq!(DatasourceId::CpanMakefile.as_str(), "cpan_makefile");
764 assert_eq!(
765 DatasourceId::DebianInstalledFilesList.as_str(),
766 "debian_installed_files_list"
767 );
768 assert_eq!(
769 DatasourceId::DebianOriginalSourceTarball.as_str(),
770 "debian_original_source_tarball"
771 );
772 assert_eq!(
773 DatasourceId::DebianSourceMetadataTarball.as_str(),
774 "debian_source_metadata_tarball"
775 );
776 assert_eq!(
777 DatasourceId::GemArchiveExtracted.as_str(),
778 "gem_archive_extracted"
779 );
780 assert_eq!(DatasourceId::NugetNuspec.as_str(), "nuget_nuspec");
782 assert_eq!(DatasourceId::RpmSpecfile.as_str(), "rpm_specfile");
783 }
784
785 #[test]
786 fn test_canonical_serialization() {
787 let nuget_json = serde_json::to_string(&DatasourceId::NugetNuspec).unwrap();
788 assert_eq!(nuget_json, r#""NugetNuspec""#);
789
790 let rpm_json = serde_json::to_string(&DatasourceId::RpmSpecfile).unwrap();
791 assert_eq!(rpm_json, r#""RpmSpecfile""#);
792 }
793
794 #[test]
795 fn test_from_str_uses_canonical_ids_and_rejects_legacy_typos() {
796 assert_eq!(
797 DatasourceId::from_str("nuget_nuspec").unwrap(),
798 DatasourceId::NugetNuspec
799 );
800 assert_eq!(
801 DatasourceId::from_str("rpm_specfile").unwrap(),
802 DatasourceId::RpmSpecfile
803 );
804 assert!(DatasourceId::from_str("nuget_nupsec").is_err());
808 assert!(DatasourceId::from_str("rpm_spefile").is_err());
809 }
810}