use crate::network::{ForgeApi, ForgeApiKind, forgejo::ForgejoApi, gitlab::GitLabApi};
use secrecy::SecretString;
use std::sync::OnceLock;
use url::Url;
#[derive(Clone, Debug)]
pub struct Config {
pub certs_dir: String,
pub forge_kind: ForgeApiKind,
pub forge_list_users: bool,
pub forge_secret_key: Option<SecretString>,
pub forge_url: Url,
pub port: u16,
}
impl Default for Config {
fn default() -> Self {
Self {
certs_dir: String::from(".certs"),
forge_kind: ForgeApiKind::Forgejo,
forge_list_users: false,
forge_secret_key: None,
forge_url: Url::parse("http://localhost:3000").expect("Valid default URL"),
port: 1965,
}
}
}
impl Config {
pub fn forge_api(&self) -> &'static Box<dyn ForgeApi> {
static API: OnceLock<Box<dyn ForgeApi>> = OnceLock::new();
API.get_or_init(|| {
let kind = self.forge_kind;
let forge_url = self.forge_url.clone();
let private_token = &self.forge_secret_key;
println!("Preparing {kind} API");
match kind {
ForgeApiKind::Forgejo | ForgeApiKind::Gitea => {
Box::new(ForgejoApi::from_url(forge_url, kind, private_token))
}
ForgeApiKind::GitLab => {
Box::new(GitLabApi::from_url(forge_url, kind, private_token))
}
}
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_forge_api_same_each_time() {
let mut config = Config::default();
let api1 = config.forge_api();
config.forge_kind = ForgeApiKind::Gitea;
let api2 = config.forge_api();
assert_eq!(api1.kind(), api2.kind());
}
}