Skip to main content

git_same/types/
provider.rs

1//! Provider type definitions.
2//!
3//! Defines the supported Git hosting providers and their identifiers.
4
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8/// Identifies which Git hosting provider a repository belongs to.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
10pub enum ProviderKind {
11    /// GitHub.com (public)
12    #[serde(rename = "github")]
13    #[default]
14    GitHub,
15    /// GitHub Enterprise (Cloud & Server)
16    #[serde(rename = "github-enterprise")]
17    GitHubEnterprise,
18    /// GitLab.com
19    #[serde(rename = "gitlab")]
20    GitLab,
21    /// GitLab Dedicated & Self-Managed
22    #[serde(rename = "gitlab-self-managed")]
23    GitLabSelfManaged,
24    /// Codeberg.org
25    #[serde(rename = "codeberg")]
26    Codeberg,
27    /// Bitbucket.org
28    #[serde(rename = "bitbucket")]
29    Bitbucket,
30}
31
32impl ProviderKind {
33    /// Returns a stable slug for path templating and cache keys.
34    pub fn slug(&self) -> &'static str {
35        match self {
36            ProviderKind::GitHub => "github",
37            ProviderKind::GitHubEnterprise => "github-enterprise",
38            ProviderKind::GitLab => "gitlab",
39            ProviderKind::GitLabSelfManaged => "gitlab-self-managed",
40            ProviderKind::Codeberg => "codeberg",
41            ProviderKind::Bitbucket => "bitbucket",
42        }
43    }
44
45    /// Returns the default API base URL for this provider.
46    pub fn default_api_url(&self) -> &'static str {
47        match self {
48            ProviderKind::GitHub => "https://api.github.com",
49            ProviderKind::GitHubEnterprise => "", // Must be configured
50            ProviderKind::GitLab => "https://gitlab.com/api/v4",
51            ProviderKind::GitLabSelfManaged => "", // Must be configured
52            ProviderKind::Codeberg => "https://codeberg.org/api/v1",
53            ProviderKind::Bitbucket => "https://api.bitbucket.org/2.0",
54        }
55    }
56
57    /// Returns the default git host for SSH URLs.
58    pub fn default_ssh_host(&self) -> &'static str {
59        match self {
60            ProviderKind::GitHub => "github.com",
61            ProviderKind::GitHubEnterprise => "", // Must be configured
62            ProviderKind::GitLab => "gitlab.com",
63            ProviderKind::GitLabSelfManaged => "", // Must be configured
64            ProviderKind::Codeberg => "codeberg.org",
65            ProviderKind::Bitbucket => "bitbucket.org",
66        }
67    }
68
69    /// Returns true if this provider requires custom URL configuration.
70    pub fn requires_custom_url(&self) -> bool {
71        matches!(
72            self,
73            ProviderKind::GitHubEnterprise | ProviderKind::GitLabSelfManaged
74        )
75    }
76
77    /// Returns the human-readable name for this provider.
78    pub fn display_name(&self) -> &'static str {
79        match self {
80            ProviderKind::GitHub => "GitHub",
81            ProviderKind::GitHubEnterprise => "GitHub Enterprise",
82            ProviderKind::GitLab => "GitLab",
83            ProviderKind::GitLabSelfManaged => "GitLab Self-Managed",
84            ProviderKind::Codeberg => "Codeberg",
85            ProviderKind::Bitbucket => "Bitbucket",
86        }
87    }
88
89    /// Returns all supported provider kinds.
90    pub fn all() -> &'static [ProviderKind] {
91        &[
92            ProviderKind::GitHub,
93            ProviderKind::GitHubEnterprise,
94            ProviderKind::GitLab,
95            ProviderKind::GitLabSelfManaged,
96            ProviderKind::Codeberg,
97            ProviderKind::Bitbucket,
98        ]
99    }
100}
101
102impl fmt::Display for ProviderKind {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        write!(f, "{}", self.display_name())
105    }
106}
107
108impl std::str::FromStr for ProviderKind {
109    type Err = String;
110
111    fn from_str(s: &str) -> Result<Self, Self::Err> {
112        match s.to_lowercase().as_str() {
113            "github" | "gh" => Ok(ProviderKind::GitHub),
114            "github-enterprise" | "ghe" | "github_enterprise" => Ok(ProviderKind::GitHubEnterprise),
115            "gitlab" | "gl" => Ok(ProviderKind::GitLab),
116            "gitlab-self-managed" | "glsm" | "gitlab_self_managed" => {
117                Ok(ProviderKind::GitLabSelfManaged)
118            }
119            "codeberg" | "cb" => Ok(ProviderKind::Codeberg),
120            "bitbucket" | "bb" => Ok(ProviderKind::Bitbucket),
121            _ => Err(format!(
122                "Unknown provider: '{}'. Supported: github, github-enterprise, gitlab, \
123                 gitlab-self-managed, codeberg, bitbucket",
124                s
125            )),
126        }
127    }
128}
129
130#[cfg(test)]
131#[path = "provider_tests.rs"]
132mod tests;