Skip to content

Commit

Permalink
add feature-flag for integrated frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
zUnixorn committed Oct 13, 2023
1 parent d5bcb05 commit 929b310
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 30 deletions.
14 changes: 10 additions & 4 deletions backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"]
2 changes: 2 additions & 0 deletions backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

13 changes: 10 additions & 3 deletions backend/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
},
}
}

Expand Down
61 changes: 38 additions & 23 deletions backend/src/endpoints.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -20,12 +18,19 @@ pub async fn index(req: HttpRequest) -> Result<impl Responder, Box<dyn std::erro
return Ok(NamedFile::open(path)?.into_response(&req));
}

let response = get_embedded_file("index.html").unwrap();
Ok(
HttpResponse::Ok()
.content_type(response.0)
.body(response.1)
)
#[cfg(feature = "integrated-frontend")]
{
let response = get_embedded_file("index.html").unwrap();

return Ok(
HttpResponse::Ok()
.content_type(response.0)
.body(response.1)
);
}

#[allow(unreachable_code)]
{ unreachable!("If this is encountered, the `frontend_location` config key was not ensured to be present"); }
}

#[get("/{shortened_url:.*}")]
Expand Down Expand Up @@ -132,33 +137,43 @@ pub async fn serve_file(asset: web::Path<String>, req: HttpRequest) -> Result<im
return Ok(NamedFile::open(path)?.into_response(&req));
}

// Tuple of MIME Type and Content.
let response_opt: Option<(&str, &[u8])> = 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
})
}
Expand Down

0 comments on commit 929b310

Please sign in to comment.