use std::fmt::{Display, self};
use cnctd_rest::Rest;
use serde::{Deserialize, Serialize};
use anyhow::anyhow;
use crate::{GitProvider, api::rest::GitRest};
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct GitAccount {
pub provider: GitProvider,
pub login: String,
pub token: String,
pub personal_url: String,
pub org_urls: Vec<String>,
pub default_url: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct GitUser {
pub login: String,
}
impl GitUser {
pub async fn get(provider: &GitProvider, token: &str) -> anyhow::Result<Self> {
match provider {
GitProvider::GitHub => {
let user: Self = Rest::get_with_auth("https://api.github.com/user", token).await?;
Ok(user)
}
_ => {
Err(anyhow!("Provider not supported yet"))
}
}
}
}
impl Display for GitAccount {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let display_str = &self.login;
write!(f, "{}", display_str)
}
}
impl GitAccount {
pub async fn new(provider: GitProvider, token: &str) -> anyhow::Result<Self> {
let login = GitUser::get(&provider, token).await?.login;
let personal_url = match provider {
GitProvider::GitHub => format!("https://github.com/{}", login),
GitProvider::GitLab => format!("https://gitlab.com/{}", login),
GitProvider::Bitbucket => format!("https://bitbucket.org/{}", login),
};
let org_urls = GitRest::org_urls(&provider, token).await?;
Ok(Self {
provider,
login: login.to_string(),
token: token.to_string(),
personal_url: personal_url.clone(),
org_urls,
default_url: personal_url,
})
}
pub fn url_is_org(&self) -> bool {
self.org_urls.contains(&self.default_url)
}
pub fn get_org_from_url(&self) -> String {
let parts: Vec<&str> = self.default_url.split('/').collect();
parts.last().map(|s| s.to_string()).unwrap()
}
}