use serde::Deserialize;
use std::str::FromStr;
use tide::log;
use crate::messages::{ErrorMsg, SuccessMsg};
#[derive(Debug, Deserialize, Clone)]
pub struct LicenseDatabase {
pub licenses: Vec<License>,
}
impl Default for LicenseDatabase {
fn default() -> Self {
Self {
licenses: Default::default(),
}
}
}
pub trait Queryable {
fn get_licenses(self: &Self, chunk_size: usize) -> Option<String>;
fn get_detailed_licenses(self: &Self) -> Option<String>;
fn get_license(self: &Self, id: &str) -> Option<License>;
}
impl Queryable for LicenseDatabase {
fn get_licenses(self: &Self, chunk_size: usize) -> Option<String> {
let result = self
.licenses
.iter()
.map(|license| license.id.clone())
.collect::<Vec<String>>()
.chunks(chunk_size)
.map(|chunk| chunk.join(", "))
.collect::<Vec<String>>()
.join("\n");
if result.is_empty() {
log::warn!("{}", ErrorMsg::NoLicensesAvailable);
None
} else {
Some(result)
}
}
fn get_detailed_licenses(self: &Self) -> Option<String> {
const PADDING: usize = 20;
let result: String = self
.licenses
.iter()
.map(|license| {
format!(
"{:padding$}{}",
license.id,
license.description,
padding = PADDING
)
})
.collect::<Vec<String>>()
.join("\n");
if result.is_empty() {
log::warn!("{}", ErrorMsg::NoLicensesAvailable);
None
} else {
Some(result)
}
}
fn get_license(self: &Self, id: &str) -> Option<License> {
let query: Option<License> = self
.licenses
.iter()
.map(|license| license.clone())
.find(|license| license.id.eq(id));
query
}
}
impl LicenseDatabase {
pub fn load(file: String) -> Option<LicenseDatabase> {
let db_path: std::path::PathBuf =
std::path::PathBuf::from_str(file.as_str()).unwrap_or_default();
match std::fs::read_to_string(db_path.as_path()) {
Ok(contents) => {
let database: LicenseDatabase = serde_yaml::from_str(&contents).unwrap();
log::info!("{}", SuccessMsg::DatabaseLoaded);
Some(database)
}
Err(_) => {
log::error!("{}", ErrorMsg::DatabaseError);
None
}
}
}
}
#[derive(Debug, Deserialize, Clone)]
pub struct License {
pub id: String,
pub filename: String,
pub description: String,
}