From 9fd75dae1cbf7d3803991dafdc412301fae62d3a Mon Sep 17 00:00:00 2001 From: holly sparkles Date: Tue, 3 Oct 2023 21:35:33 +0200 Subject: [PATCH] feat: add retrieving license text --- src/data.rs | 16 ++++++++++++++++ src/main.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/data.rs b/src/data.rs index 2d8fe1c..ef2ae7a 100644 --- a/src/data.rs +++ b/src/data.rs @@ -7,6 +7,22 @@ pub struct LicenseDatabase { pub licenses: Vec, } +pub trait Queryable { + fn get_license(self: &Self, id: &str) -> Option; +} + +impl Queryable for LicenseDatabase { + 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(file: &Path) -> LicenseDatabase { let file_contents = std::fs::read_to_string(file).unwrap(); diff --git a/src/main.rs b/src/main.rs index 9e4c52c..9998824 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,15 @@ +use async_std::{ + fs, + path::{Path, PathBuf}, +}; use data::LicenseDatabase; use jealousy::FromEnv; use serde::Deserialize; -use std::{net::Ipv4Addr, path::PathBuf, str::FromStr}; +use std::{net::Ipv4Addr, str::FromStr}; use tide::{http::mime, log, Response, Result, Server, StatusCode}; +use crate::data::{License, Queryable}; + mod data; #[macro_use] @@ -41,19 +47,20 @@ lazy_static! { // 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 config = Config::from_env().unwrap(); - let db_path: PathBuf = PathBuf::from_str(&config.database).unwrap(); + let db_path: std::path::PathBuf = std::path::PathBuf::from_str(&config.database).unwrap(); let database: LicenseDatabase = LicenseDatabase::load_file(db_path.as_path()); - database }; } +const ERROR_LICENSE_NOT_FOUND: &str = + " is undefined. use the 'list' endpoint to see defined licenses."; + #[async_std::main] async fn main() -> Result<()> { log::start(); - let config = Config::from_env(); - match config { + match Config::from_env() { Ok(config) => { let mut app = tide::new(); @@ -63,7 +70,7 @@ async fn main() -> Result<()> { .await?; } Err(_) => (), // jealousy prints its own error message so this is safe to ignore...i think - } + }; Ok(()) } @@ -148,8 +155,47 @@ async fn get_detailed_license_list(req: tide::Request<()>) -> tide::Result) -> tide::Result { log::info!("{:?}", req); - Ok(build_response( - StatusCode::Ok, - format!("{}", "Content of requested license goes here").to_string(), - )) + let config = Config::from_env().unwrap(); + + // remove prefix from requested route + // TODO: make this better + let request = req.url().path().strip_prefix("/").unwrap_or(""); + + let response = match DATABASE.get_license(request) { + Some(license) => { + // is there a better way to do this? + let source_dir = PathBuf::from(&config.database); + let source_dir = source_dir.parent().unwrap_or(Path::new("")); + + let mut license_file_path = PathBuf::from(source_dir); + license_file_path.push(license.filename); + + match fs::read_to_string(&license_file_path).await { + Ok(contents) => { + build_response(StatusCode::Accepted, contents.trim_end().to_string()) + } + Err(_) => { + log::error!( + "Unable to read `{}`.", + license_file_path.to_string_lossy().to_string() + ); + + build_response( + StatusCode::NotFound, + format!("ERROR - `{}`{}", request, ERROR_LICENSE_NOT_FOUND).to_string(), + ) + } + } + } + None => { + log::error!("License not found: `{}`", request); + + build_response( + StatusCode::NotFound, + format!("ERROR - `{}`{}", request, ERROR_LICENSE_NOT_FOUND).to_string(), + ) + } + }; + + Ok(response) } -- libgit2 1.7.2