index : license-api-rs.git

ascending towards madness

use serde::Deserialize;
use std::str::FromStr;
use tide::log;

#[derive(Debug, Deserialize, Clone)]
pub struct LicenseDatabase {
    pub licenses: Vec<License>,
}

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!("License database not found!");
            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!("License database not found!");
            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) -> LicenseDatabase {
        // TODO: error handling and use log::info when done
        // not sure if i should validate the unwrap since main won't start if there is an error...
        let db_path: std::path::PathBuf = std::path::PathBuf::from_str(file.as_str()).unwrap();
        let file_contents = std::fs::read_to_string(db_path.as_path()).unwrap();
        let database: LicenseDatabase = serde_yaml::from_str(&file_contents).unwrap();
        database
    }
}

#[derive(Debug, Deserialize, Clone)]
pub struct License {
    pub id: String,
    pub filename: String,
    pub description: String,
}