use crate::config::{Config, GiteaConfig}; use crate::error::GeneralError; use reqwest::header::{HeaderMap, ACCEPT, AUTHORIZATION}; use reqwest::{ClientBuilder, StatusCode}; use serde::de::DeserializeOwned; use url::Url; #[derive(Debug)] pub struct Client { token: String, base_uri: String, } fn is_client_for_url(url: &Url, config: &GiteaConfig) -> bool { if url.domain() == Some(config.domain.as_str()) { return true; } false } pub(crate) fn has_client_for_url(url: &Url, config: &Config) -> bool { for c in &config.gitea { if is_client_for_url(url, c) { return true; } } false } fn client_for_url(url: &Url, config: &Config) -> Result { for c in &config.gitea { if is_client_for_url(url, c) { return Ok(Client::from_config(&c)); } } Err(GeneralError { description: format!("No gitea client found for url {}", url), }) } impl Client { pub fn from_config(config: &GiteaConfig) -> Self { Self::new(&config.token, &config.domain) } pub fn new(token: &String, domain: &String) -> Self { Client { token: token.clone(), base_uri: format!("https://{}", domain.clone()), } } pub async fn get(&self, url: Url) -> Result { let mut headers = HeaderMap::new(); headers.append(AUTHORIZATION, format!("token {}", self.token).parse()?); headers.append(ACCEPT, "application/json".parse()?); let client = ClientBuilder::new() .default_headers(headers) .build() .unwrap(); let response = client.get(url.clone()).send().await?; match response.status() { StatusCode::OK => { let result: T = response.json().await?; Ok(result) } _ => Err(GeneralError { description: format!( "Could not call GET on {:?}, error code {}", url, response.status() ), }), } } } #[cfg(test)] mod test { use super::*; #[test] fn test_is_client_for_url() { let config = GiteaConfig { domain: "gitea.champs-libres.be".into(), token: "".into(), }; assert_eq!( is_client_for_url( &Url::parse("https://gitea.champs-libres.be/something/somewhere").unwrap(), &config ), true ); assert_eq!( is_client_for_url( &Url::parse("https://somewhere.else/something/somewhere").unwrap(), &config ), false ); } }