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, } impl Default for LicenseDatabase { fn default() -> Self { Self { licenses: Default::default(), } } } pub trait Queryable { fn get_licenses(self: &Self, chunk_size: usize) -> Option; fn get_detailed_licenses(self: &Self) -> Option; fn get_license(self: &Self, id: &str) -> Option; } impl Queryable for LicenseDatabase { fn get_licenses(self: &Self, chunk_size: usize) -> Option { let result = self .licenses .iter() .map(|license| license.id.clone()) .collect::>() .chunks(chunk_size) .map(|chunk| chunk.join(", ")) .collect::>() .join("\n"); if result.is_empty() { log::warn!("{}", ErrorMsg::NoLicensesAvailable); None } else { Some(result) } } fn get_detailed_licenses(self: &Self) -> Option { const PADDING: usize = 20; let result: String = self .licenses .iter() .map(|license| { format!( "{:padding$}{}", license.id, license.description, padding = PADDING ) }) .collect::>() .join("\n"); if result.is_empty() { log::warn!("{}", ErrorMsg::NoLicensesAvailable); None } else { Some(result) } } fn get_license(self: &Self, id: &str) -> Option { let query: Option = self .licenses .iter() .map(|license| license.clone()) .find(|license| license.id.eq(id)); query } } impl LicenseDatabase { pub fn load(file: String) -> Option { // TODO: error handling and use log::info when done 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, }