use std::io::Write;
use anyhow::{bail, Context, Result};
use regex::Regex;
use tabwriter::TabWriter;
use super::types::{CreateProject, Project, Quotas, SingleProjectResponse, Sku, SkuResponse};
use crate::state::http::HttpClient;
pub fn format_projects(projects: &Vec<Project>, title: bool) -> Vec<String> {
let mut tw = TabWriter::new(vec![]);
if title {
writeln!(&mut tw, "NAME\tNAMESPACE\tID\tCREATED\tTYPE").unwrap();
}
for project in projects {
writeln!(
&mut tw,
"{}\t/{}\t{}\t{}\t{}",
project.name.clone(),
project.namespace,
project.id,
project.created_at,
project.type_,
)
.unwrap();
}
String::from_utf8(tw.into_inner().unwrap())
.unwrap()
.lines()
.map(std::string::ToString::to_string)
.collect()
}
pub fn format_project(project: &Project) -> String {
format_projects(&vec![project.clone()], false)[0].clone()
}
pub async fn create_project(
http: &HttpClient,
name: &str,
namespace: &str,
payment_method_id: &str,
) -> Result<Project> {
let data = http
.request::<SingleProjectResponse>(
"POST",
"/projects",
Some((
serde_json::to_vec(&CreateProject {
name: name.to_string(),
namespace: namespace.to_string(),
payment_method_id: payment_method_id.to_string(),
})
.unwrap()
.into(),
"application/json",
)),
)
.await?
.ok_or_else(|| anyhow::anyhow!("Error while parsing response"))?
.project;
Ok(data)
}
pub fn validate_namespace(namespace: &str) -> Result<()> {
let regex = Regex::new(r"(?i)[a-z0-9_]")?;
if namespace.len() > 15 {
bail!("Namespace must be less than 15 characters")
} else if !regex.is_match(namespace) {
bail!("Namespace must contain only letters, numbers and underscores")
}
Ok(())
}
pub async fn get_quotas(http: &HttpClient, project_id: &str) -> Result<Quotas> {
http.request::<Quotas>("GET", &format!("/quotas?project={project_id}"), None)
.await?
.context("Error while parsing response")
}
pub async fn get_skus(http: &HttpClient) -> Result<Vec<Sku>> {
Ok(http
.request::<SkuResponse>("GET", "/skus", None)
.await?
.context("Error while parsing response")?
.skus)
}