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(-)
@@ -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> {
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
}
}
}
}
@@ -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 => { "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!",
}
}
}
@@ -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<()> {
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_route.at(":license").get(get_requested_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);
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(),
)
}