generated from alecodes/base-template
refactor: change asset handling
read assets from the template state instead of path to be able to embed them into the binary instead of reading them form a path
This commit is contained in:
parent
3ff1f26cc4
commit
1871610770
4 changed files with 53 additions and 9 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -286,6 +286,7 @@ dependencies = [
|
||||||
"axum-sqlx-tx",
|
"axum-sqlx-tx",
|
||||||
"chrono",
|
"chrono",
|
||||||
"figment",
|
"figment",
|
||||||
|
"mime_guess",
|
||||||
"minijinja",
|
"minijinja",
|
||||||
"minijinja-embed",
|
"minijinja-embed",
|
||||||
"notify",
|
"notify",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ axum-htmx = { version = "0.7.0", features = ["auto-vary", "serde", "guards"] }
|
||||||
axum-sqlx-tx = "0.10.0"
|
axum-sqlx-tx = "0.10.0"
|
||||||
chrono = { version = "0.4.39", features = ["serde"] }
|
chrono = { version = "0.4.39", features = ["serde"] }
|
||||||
figment = { version = "0.10.19", features = ["env", "toml"] }
|
figment = { version = "0.10.19", features = ["env", "toml"] }
|
||||||
|
mime_guess = "2.0.5"
|
||||||
minijinja = { version = "2.7.0", features = ["loader"] }
|
minijinja = { version = "2.7.0", features = ["loader"] }
|
||||||
minijinja-embed = "2.7.0"
|
minijinja-embed = "2.7.0"
|
||||||
notify = "8.0.0"
|
notify = "8.0.0"
|
||||||
|
|
|
||||||
30
src/error.rs
30
src/error.rs
|
|
@ -6,7 +6,7 @@ use tracing::debug;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
pub type ResultTemplate = std::result::Result<Html<String>, Error>;
|
pub type ResultTemplate = Result<Html<String>>;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
@ -33,15 +33,35 @@ pub enum Error {
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Config(#[from] figment::Error),
|
Config(#[from] figment::Error),
|
||||||
|
|
||||||
|
#[error("")]
|
||||||
|
HTTP(StatusCode),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StatusCode> for Error {
|
||||||
|
fn from(value: StatusCode) -> Self {
|
||||||
|
Self::HTTP(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoResponse for Error {
|
impl IntoResponse for Error {
|
||||||
fn into_response(self) -> axum::response::Response {
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
let catch_all = (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"An unexpected error has ocurred!",
|
||||||
|
);
|
||||||
let (status, message) = match self {
|
let (status, message) = match self {
|
||||||
_ => (
|
Error::Template(ref error) => {
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
if let minijinja::ErrorKind::TemplateNotFound = error.kind() {
|
||||||
"An unexpected error has ocurred!",
|
(
|
||||||
),
|
StatusCode::NOT_FOUND,
|
||||||
|
"The requested resource was not found.",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
catch_all
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => catch_all,
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(error = ?self);
|
debug!(error = ?self);
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,39 @@
|
||||||
use axum::{extract::State, response::Html, routing::get, Router};
|
use axum::{
|
||||||
|
extract::{Path, State},
|
||||||
|
http::{header, HeaderMap, HeaderValue},
|
||||||
|
response::Html,
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
use axum_htmx::HxRequest;
|
use axum_htmx::HxRequest;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use minijinja::context;
|
use minijinja::context;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sqlx::prelude::FromRow;
|
use sqlx::prelude::FromRow;
|
||||||
use tower_http::services::ServeDir;
|
|
||||||
|
|
||||||
use crate::{AppState, ResultTemplate, Tx};
|
use crate::{AppState, Result, ResultTemplate, Tx};
|
||||||
|
|
||||||
pub fn new() -> Router<AppState> {
|
pub fn new() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(handler_home))
|
.route("/", get(handler_home))
|
||||||
.nest_service("/assets", ServeDir::new("dist/assets"))
|
.route("/assets/{*asset}", get(handle_assets))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_assets(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(asset): Path<String>,
|
||||||
|
) -> Result<(HeaderMap, String)> {
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
|
||||||
|
let mime = mime_guess::from_path(&asset).first_raw();
|
||||||
|
|
||||||
|
if let Some(mime) = mime {
|
||||||
|
headers.insert(header::CONTENT_TYPE, HeaderValue::from_static(mime));
|
||||||
|
}
|
||||||
|
|
||||||
|
let template = state.tmpl_env.get_template(&format!("assets/{}", asset))?;
|
||||||
|
|
||||||
|
Ok((headers, template.render(context!())?))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromRow, Debug, Serialize)]
|
#[derive(FromRow, Debug, Serialize)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue