use crate::network::{forgejo::ForgejoApi, gitlab::GitLabApi, ForgeApi, ForgeApiKind};
use secrecy::SecretString;
use std::sync::OnceLock;
use url::Url;
#[derive(Clone, Debug)]
pub struct Config {
pub crate_version: &'static str,
pub forge_list_users: bool,
pub forge_kind: ForgeApiKind,
pub forge_url: Url,
pub forge_secret_key: Option<SecretString>,
pub certs_dir: String,
}
impl Default for Config {
fn default() -> Self {
Self {
crate_version: "x.x.x",
forge_list_users: false,
forge_kind: ForgeApiKind::Forgejo,
forge_url: Url::parse("http://localhost:3000").expect("Valid default URL"),
forge_secret_key: None,
certs_dir: String::from(".certs"),
}
}
}
impl Config {
pub fn forge_api(&self) -> &'static Box<dyn ForgeApi> {
static API: OnceLock<Box<dyn ForgeApi>> = OnceLock::new();
return 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 => {
return Box::new(ForgejoApi::from_url(forge_url, kind));
}
ForgeApiKind::GitLab => {
return 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());
}
}