diff --git a/backend/Cargo.toml b/backend/Cargo.toml index a30c817..4ba54eb 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -23,8 +23,6 @@ serde = "1.0.189" serde_json = "1.0.107" toml = "0.8.2" -static-files = "0.2" - chrono = "0.4.31" thiserror = "1.0.49" @@ -37,6 +35,14 @@ dotenvy = "0.15.7" version = "0.6.3" features = ["runtime-tokio-rustls", "chrono", "migrate", "offline", "macros", "sqlite"] -[build-dependencies] -static-files = "0.2" +[dependencies.static-files] +version = "0.2" +optional = true + +[build-dependencies.static-files] +version = "0.2" +#optional = true +[features] +default = ["integrated-frontend"] +integrated-frontend = ["static-files"] diff --git a/backend/build.rs b/backend/build.rs index 718f9f1..c25c5ba 100644 --- a/backend/build.rs +++ b/backend/build.rs @@ -2,6 +2,8 @@ fn main() { // trigger recompilation when a new migration is added println!("cargo:rerun-if-changed=migrations"); + + #[cfg(feature = "integrated-frontend")] static_files::resource_dir("../frontend/dist").build().unwrap(); } diff --git a/backend/src/config.rs b/backend/src/config.rs index 66ee0a4..79fd1b8 100644 --- a/backend/src/config.rs +++ b/backend/src/config.rs @@ -48,9 +48,16 @@ impl Config { if config.frontend_location.is_none() { match std::env::var("SHORTY_WEBSITE") { - Ok(path) => { config.frontend_location = Some(path) } - Err(VarError::NotPresent) => {}, - Err(why) => { error!("{why}") } + Ok(path) => { config.frontend_location = Some(path) }, + #[allow(unused)] + Err(e) => { + #[cfg(not(feature = "integrated-frontend"))] + panic!("Shorty was compiled without the `integrated-frontend` feature, therefore the frontend_location key is mandatory"); + + if e != VarError::NotPresent { + error!("{e}"); + } + }, } } diff --git a/backend/src/endpoints.rs b/backend/src/endpoints.rs index df42488..0ad6669 100644 --- a/backend/src/endpoints.rs +++ b/backend/src/endpoints.rs @@ -1,8 +1,6 @@ -use std::collections::HashMap; use actix_files::NamedFile; use actix_web::{get, HttpRequest, HttpResponse, post, Responder, web}; -use static_files::Resource; -use tracing::{debug, info, warn}; +use tracing::{debug, info}; use crate::CONFIG; use crate::error::ShortyError; @@ -20,12 +18,19 @@ pub async fn index(req: HttpRequest) -> Result, req: HttpRequest) -> Result = get_embedded_file(asset.as_str()); - - - if let Some(response) = response_opt { - Ok( - HttpResponse::Ok() - .content_type(response.0) - .body(response.1) - ) - } else { - Ok(HttpResponse::NotFound().finish()) + #[cfg(feature = "integrated-frontend")] + { + // Tuple of MIME Type and Content. + let response_opt: Option<(&str, &[u8])> = get_embedded_file(asset.as_str()); + + + return if let Some(response) = response_opt { + Ok( + HttpResponse::Ok() + .content_type(response.0) + .body(response.1) + ) + } else { + Ok(HttpResponse::NotFound().finish()) + }; } + + #[allow(unreachable_code)] + { unreachable!("If this is encountered, the `frontend_location` config key was not ensured to be present"); } } +#[cfg(feature = "integrated-frontend")] include!(concat!(env!("OUT_DIR"), "/generated.rs")); /// Returns a Tuple of Mime Type (as &str) and file content (as &[u8]). +#[cfg(feature = "integrated-frontend")] fn get_embedded_file(file: &str) -> Option<(&'static str, &'static [u8])> { - let resources: HashMap<&str, Resource> = generate(); + use std::collections::HashMap; + + let resources: HashMap<&str, static_files::Resource> = generate(); debug!("Getting embedded file: {file}"); resources.get(file).map(|file| { (file.mime_type, file.data) }).or_else(|| { - warn!("Got request for {file} but couldn't find embedded asset."); + tracing::warn!("Got request for {file} but couldn't find embedded asset."); None }) }