git-gemini-forge 0.5.2

A simple Gemini server that serves a read-only view of public repositories from a Git forge.
use super::converters::{
	gitlab_contents_to_contents, gitlab_metadata_to_server_version, gitlab_project_id,
	gitlab_project_to_repo, gitlab_user_to_user,
};
use crate::network::error;
use crate::network::responses::*;
use crate::network::{ForgeApi, ForgeApiKind};
use secrecy::SecretString;
use url::Url;

/// Describes the GitLab API.
///
/// See https://docs.gitlab.com/ee/api/api_resources.html
#[derive(Clone, Debug)]
pub struct GitLabApi {
	_base_url: Url,
	_kind: ForgeApiKind,
	_private_token: Option<SecretString>,
}

impl GitLabApi {
	/// Constructs an API from the given forge URL.
	pub fn from_url(
		forge_url: Url,
		kind: ForgeApiKind,
		private_token: &Option<SecretString>,
	) -> Self {
		let base_url: Url = forge_url.join("/api/v4/").unwrap();
		return GitLabApi {
			_base_url: base_url,
			_kind: kind,
			_private_token: private_token.clone(),
		};
	}

	/// The private API token.
	pub fn private_token(&self) -> &Option<SecretString> {
		return &self._private_token;
	}
}

impl ForgeApi for GitLabApi {
	fn kind(&self) -> ForgeApiKind {
		return self._kind;
	}

	fn base_url(&self) -> &Url {
		return &self._base_url;
	}

	fn get_branches(
		&self,
		username: &str,
		project_pathname: &str,
	) -> Result<Vec<Branch>, error::Error> {
		let project_id = gitlab_project_id(username, project_pathname);
		return super::get_branches(self, project_id);
	}

	fn get_file_tree(
		&self,
		username: &str,
		project_pathname: &str,
	) -> Result<Vec<RepoContents>, error::Error> {
		let project_id = gitlab_project_id(username, project_pathname);
		return super::get_file_tree(self, project_id).map(|tree| {
			return tree.iter().map(gitlab_contents_to_contents).collect();
		});
	}

	fn get_recent_repos(&self) -> Result<Vec<Repo>, error::Error> {
		return super::get_recent_repos(self).map(|projects| {
			return projects
				.iter()
				.filter(|p| p.default_branch.is_some()) // ignore empty projects
				.map(gitlab_project_to_repo)
				.collect();
		});
	}

	fn get_repo(&self, username: &str, project_pathname: &str) -> Result<Repo, error::Error> {
		let project_id = gitlab_project_id(username, project_pathname);
		return super::get_repo(self, project_id).map(|p| gitlab_project_to_repo(&p));
	}

	fn get_user_repos(&self, username: &str) -> Result<Vec<Repo>, error::Error> {
		return super::get_user_repos(self, username).map(|projects| {
			return projects.iter().map(gitlab_project_to_repo).collect();
		});
	}

	fn get_users(&self) -> Result<Vec<User>, error::Error> {
		return super::get_users(self).map(|users| {
			return users.iter().map(gitlab_user_to_user).collect();
		});
	}

	fn get_version(&self) -> Result<ServerVersion, error::Error> {
		return super::get_version(self).map(|v| gitlab_metadata_to_server_version(&v));
	}
}