index : license-api-rs.git

ascending towards madness

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> {
        // 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,
}