index : license-api-rs.git

ascending towards madness

author holly sparkles <sparkles@holly.sh> 2023-10-08 19:17:46.0 +00:00:00
committer holly sparkles <sparkles@holly.sh> 2023-10-08 19:17:46.0 +00:00:00
commit
9ecb54ff39cdb50e5082dbe1f0ce5cd64d94b6a8 [patch]
tree
186761cdc43cc9d2c0dd38afa3fa2320a7e23845
parent
da15798c84bccbfc13fddd94c38b4ac69df5388c
download
9ecb54ff39cdb50e5082dbe1f0ce5cd64d94b6a8.tar.gz

refactor: move error messages to errors module, improve errors, rustfmt



Diff

 src/data.rs   | 34 ++++++++++++++++++++++++++--------
 src/errors.rs | 35 +++++++++++++++++++++++++++++++++++
 src/main.rs   | 48 ++++++++++++++++++++++++------------------------
 3 files changed, 85 insertions(+), 32 deletions(-)

diff --git a/src/data.rs b/src/data.rs
index 2447ca3..e6ad7b0 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -2,11 +2,21 @@ use serde::Deserialize;
use std::str::FromStr;
use tide::log;

use crate::errors::{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>;
@@ -26,7 +36,7 @@ impl Queryable for LicenseDatabase {
            .join("\n");

        if result.is_empty() {
            log::warn!("License database not found!");
            log::warn!("{}", ErrorMsg::NoLicensesAvailable.as_str());
            None
        } else {
            Some(result)
@@ -51,7 +61,7 @@ impl Queryable for LicenseDatabase {
            .join("\n");

        if result.is_empty() {
            log::warn!("License database not found!");
            log::warn!("{}", ErrorMsg::NoLicensesAvailable.as_str());
            None
        } else {
            Some(result)
@@ -70,13 +80,21 @@ impl Queryable for LicenseDatabase {
}

impl LicenseDatabase {
    pub fn load(file: String) -> LicenseDatabase {
    pub fn load(file: String) -> Option<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
        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.as_str());
                Some(database)
            }
            Err(_) => {
                log::error!("{}", ErrorMsg::DatabaseError.as_str());
                None
            }
        }
    }
}

diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..0ed1956
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,35 @@
#[derive(Debug)]
pub enum ErrorMsg {
    DatabaseError,
    NoLicensesAvailable,
    InvalidLicenseRequest,
    InvalidLicense,
    LicenseReadError,
}

impl ErrorMsg {
    pub fn as_str(&self) -> &str {
        match *self {
            ErrorMsg::LicenseReadError => "Unable to read license file:",
            ErrorMsg::DatabaseError => "Unable to load or parse license database.",
            ErrorMsg::NoLicensesAvailable => "No licenses found.",
            ErrorMsg::InvalidLicenseRequest => { //TODO: make this not hardcoded
                "Invalid license. use the 'list' or 'list/all' endpoints to see defined licenses."
            }
            ErrorMsg::InvalidLicense => "Invalid license requested:",
        }
    }
}

#[derive(Debug)]
pub enum SuccessMsg {
    DatabaseLoaded,
}

impl SuccessMsg {
    pub fn as_str(&self) -> &str {
        match *self {
            SuccessMsg::DatabaseLoaded => "Database loaded successfully!",
        }
    }
}
diff --git a/src/main.rs b/src/main.rs
index 0ba63ec..07abf2c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,15 +8,12 @@ use tide::{http::mime, log, Response, Result, Server, StatusCode};
use crate::{
    config::{RunningConfig, ServerConfig},
    data::Queryable,
    errors::ErrorMsg,
};

mod config;
mod data;

const ERROR_NO_LICENSES_FOUND: &str =
	"No licenses found.";
const ERROR_LICENSE_NOT_FOUND: &str =
    "Invalid license. use the 'list' or 'list/all' endpoints to see defined licenses.";
mod errors;

#[async_std::main]
async fn main() -> Result<()> {
@@ -27,7 +24,7 @@ async fn main() -> Result<()> {
            // TODO: fix the borrow issue here
            let run_config = RunningConfig {
                config: config.clone(),
                database: LicenseDatabase::load(config.database.clone()),
                database: LicenseDatabase::load(config.database.clone()).unwrap_or_default(),
            };

            let mut app = tide::with_state(run_config);
@@ -48,27 +45,29 @@ fn create_routes(server: &mut Server<RunningConfig>) {
    let url = server.clone().state().config.base_url.clone();
    let mut base_route = server.at(&url);

	// BASE_URL/<license>
	base_route.at(":license").get(get_requested_license);
    // BASE_URL/<license>
    base_route.at(":license").get(get_requested_license);

	/*
	BASE_URL/list
	BASE_URL/full
	BASE_URL/list/
	BASE_URL/full/
	*/
    /*
    BASE_URL/list
    BASE_URL/full
    BASE_URL/list/
    BASE_URL/full/
    */
    base_route.at(":license").get(get_requested_license);
    base_route.at("list").get(get_license_list);
    base_route.at("list/full").get(get_detailed_license_list);

    // nyaaaaa whyyyy https://github.com/http-rs/tide/issues/205
	let mut fallback_routes = base_route.at("");
	fallback_routes.get(get_welcome_message);
    let mut fallback_routes = base_route.at("");
    fallback_routes.get(get_welcome_message);
    fallback_routes.at("list/").get(get_license_list);
	fallback_routes.at("list/full/").get(get_detailed_license_list);
    fallback_routes
        .at("list/full/")
        .get(get_detailed_license_list);

	fallback_routes.at("list/*").get(get_fallback_response);
	fallback_routes.at("list/full/*").get(get_fallback_response);
    fallback_routes.at("list/*").get(get_fallback_response);
    fallback_routes.at("list/full/*").get(get_fallback_response);
}

fn build_response(status: StatusCode, data: String) -> Response {
@@ -104,7 +103,7 @@ async fn get_license_list(req: tide::Request<RunningConfig>) -> tide::Result<Res
        Some(licenses) => Ok(build_response(StatusCode::Ok, format!("{}", licenses))),
        None => Ok(build_response(
            StatusCode::NotFound,
            String::from(ERROR_NO_LICENSES_FOUND),
            String::from(ErrorMsg::NoLicensesAvailable.as_str()),
        )),
    }
}
@@ -116,7 +115,7 @@ async fn get_detailed_license_list(req: tide::Request<RunningConfig>) -> tide::R
        Some(licenses) => Ok(build_response(StatusCode::Ok, format!("{}", licenses))),
        None => Ok(build_response(
            StatusCode::NotFound,
            String::from(ERROR_NO_LICENSES_FOUND),
            String::from(ErrorMsg::NoLicensesAvailable.as_str()),
        )),
    }
}
@@ -143,7 +142,8 @@ async fn get_requested_license(req: tide::Request<RunningConfig>) -> tide::Resul
                }
                Err(_) => {
                    log::error!(
                        "Unable to read `{}`.",
                        "{} '{}'.",
                        ErrorMsg::LicenseReadError.as_str(),
                        license_file_path.to_string_lossy().to_string()
                    );

@@ -152,7 +152,7 @@ async fn get_requested_license(req: tide::Request<RunningConfig>) -> tide::Resul
            }
        }
        None => {
            log::error!("License not found: `{}`", request);
            log::error!("{} '{}'", ErrorMsg::InvalidLicense.as_str(), request);
            error_response(request)
        }
    };
@@ -163,6 +163,6 @@ async fn get_requested_license(req: tide::Request<RunningConfig>) -> tide::Resul
fn error_response(_req: &str) -> Response {
    build_response(
        StatusCode::NotFound,
        format!("{}", ERROR_LICENSE_NOT_FOUND).to_string(),
        format!("{}", ErrorMsg::InvalidLicenseRequest.as_str()).to_string(),
    )
}