Skip to main content

gen_types/
registry.rs

1//! Typed [`Registry`] — where a package was fetched from.
2//!
3//! One variant per upstream registry the fleet's adapters speak to.
4//! Adapters set the variant during parse; renderers consult it to
5//! emit the correct download URL / cache key.
6
7use serde::{Deserialize, Serialize};
8
9/// Stable identifier for the upstream package registry.
10#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
11#[serde(tag = "kind", rename_all = "kebab-case")]
12pub enum Registry {
13    /// crates.io (default for Cargo).
14    CratesIo,
15    /// npmjs.org (default for npm / yarn / pnpm).
16    Npm,
17    /// rubygems.org (default for Bundler / Gem).
18    RubyGems,
19    /// pypi.org (default for pip / poetry).
20    PyPi,
21    /// proxy.golang.org (default for go modules).
22    GoProxy,
23    /// hex.pm (default for Mix / Hex).
24    Hex,
25    /// hackage.haskell.org (default for Cabal).
26    Hackage,
27    /// packagist.org (default for Composer).
28    Packagist,
29    /// Maven Central + Gradle plugin portal.
30    Maven,
31    /// pub.dev (Dart / Flutter).
32    Pub,
33    /// OCI registry (helm charts via OCI, also caixa).
34    Oci { registry_url: String },
35    /// Operator-self-hosted private registry — adapters declare the
36    /// URL + auth shape via shikumi config.
37    Private {
38        url: String,
39        protocol: String,
40    },
41    /// Source-only — no registry; the package is consumed as a path
42    /// or git ref, never published.
43    None,
44}
45
46impl Registry {
47    /// Stable short identifier (for cache keys + diagnostics).
48    #[must_use]
49    pub const fn as_str(&self) -> &'static str {
50        match self {
51            Self::CratesIo => "crates-io",
52            Self::Npm => "npm",
53            Self::RubyGems => "rubygems",
54            Self::PyPi => "pypi",
55            Self::GoProxy => "go-proxy",
56            Self::Hex => "hex",
57            Self::Hackage => "hackage",
58            Self::Packagist => "packagist",
59            Self::Maven => "maven",
60            Self::Pub => "pub",
61            Self::Oci { .. } => "oci",
62            Self::Private { .. } => "private",
63            Self::None => "none",
64        }
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn as_str_covers_every_variant_stably() {
74        for r in [
75            Registry::CratesIo,
76            Registry::Npm,
77            Registry::RubyGems,
78            Registry::PyPi,
79            Registry::GoProxy,
80            Registry::Hex,
81            Registry::Hackage,
82            Registry::Packagist,
83            Registry::Maven,
84            Registry::Pub,
85            Registry::Oci {
86                registry_url: "ghcr.io".into(),
87            },
88            Registry::Private {
89                url: "https://internal".into(),
90                protocol: "cargo-v1".into(),
91            },
92            Registry::None,
93        ] {
94            assert!(!r.as_str().is_empty());
95        }
96    }
97
98    #[test]
99    fn round_trips_through_serde() {
100        let r = Registry::Oci {
101            registry_url: "ghcr.io/pleme-io".into(),
102        };
103        let j = serde_json::to_string(&r).unwrap();
104        let parsed: Registry = serde_json::from_str(&j).unwrap();
105        assert_eq!(r, parsed);
106    }
107}