diff --git a/src/main.rs b/src/main.rs index e656d65..79c27d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,11 @@ mod routes; mod share; mod templates; -use std::{net::SocketAddr, path::Path, fs::{self, File}}; +use std::{ + fs::{self, File}, + net::SocketAddr, + path::Path, +}; use axum::Extension; use clap::Parser; @@ -10,7 +14,7 @@ use tera::Tera; use tower_http::trace::TraceLayer; use tracing_subscriber::prelude::*; -use crate::share::{ShareInfo, ShareFile}; +use crate::share::{ShareFile, ShareInfo}; #[derive(clap::Parser)] enum Cli { @@ -96,7 +100,9 @@ async fn create_share(name: &str, update: bool) -> color_eyre::Result<()> { update_share(&share_path).await?; } - tracing::info!("Success! Created a new share in {share_path:?}. The access token is {secret:?}"); + tracing::info!( + "Success! Created a new share in {share_path:?}. The access token is {secret:?}" + ); Ok(()) } @@ -144,7 +150,8 @@ async fn update_share(path: &Path) -> color_eyre::Result<()> { tracing::info!(?path, ?filename, "adding to index"); let is_image = mime_guess::from_path(entry.path()) .first_or_octet_stream() - .type_() == mime::IMAGE; + .type_() + == mime::IMAGE; share_info.files.push(if is_image { ShareFile::Image(filename.to_owned()) } else { diff --git a/src/routes.rs b/src/routes.rs index 796b3c5..bd6975c 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,17 +1,20 @@ use std::path::Path; -use axum::{Router, routing::any_service, http::StatusCode}; +use axum::{http::StatusCode, routing::any_service, Router}; use tower_http::services::ServeDir; mod share; pub fn routes() -> Router { Router::new() - .nest("/assets", any_service(ServeDir::new(&Path::new("assets"))) - .handle_error(|err: std::io::Error| async move { - tracing::error!("unhandled error in static file server: {}", err); - (StatusCode::INTERNAL_SERVER_ERROR, "internal server error") - }) + .nest( + "/assets", + any_service(ServeDir::new(&Path::new("assets"))).handle_error( + |err: std::io::Error| async move { + tracing::error!("unhandled error in static file server: {}", err); + (StatusCode::INTERNAL_SERVER_ERROR, "internal server error") + }, + ), ) .nest("/share", share::routes()) } diff --git a/src/routes/share.rs b/src/routes/share.rs index ac3d1d7..1cdfb40 100644 --- a/src/routes/share.rs +++ b/src/routes/share.rs @@ -1,13 +1,24 @@ use std::path::{self, PathBuf}; -use axum::{response::IntoResponse, extract::{Path, FromRequest, Query}, async_trait, http::{StatusCode, Request}, Router, routing::get, body::Body}; -use serde::{Serialize, Deserialize}; +use axum::{ + async_trait, + body::Body, + extract::{FromRequest, Path, Query}, + http::{Request, StatusCode}, + response::IntoResponse, + routing::get, + Router, +}; +use serde::{Deserialize, Serialize}; use tera::Context; use tokio::fs; use tower_http::services::ServeFile; use tower_service::Service; -use crate::{templates::{Renderer, TemplateRenderer}, share::ShareInfo}; +use crate::{ + share::ShareInfo, + templates::{Renderer, TemplateRenderer}, +}; struct Share { info: ShareInfo, @@ -15,10 +26,15 @@ struct Share { } #[async_trait] -impl FromRequest for Share where B: Send { +impl FromRequest for Share +where + B: Send, +{ type Rejection = StatusCode; - async fn from_request(req: &mut axum::extract::RequestParts) -> Result { + async fn from_request( + req: &mut axum::extract::RequestParts, + ) -> Result { #[derive(Deserialize)] struct P { share: String, @@ -29,11 +45,12 @@ impl FromRequest for Share where B: Send { } let Path(P { share }) = Path::

::from_request(req).await.unwrap(); - let Query(Q { token }) = Query::::from_request(req).await.map_err(|_| StatusCode::NOT_FOUND)?; + let Query(Q { token }) = Query::::from_request(req) + .await + .map_err(|_| StatusCode::NOT_FOUND)?; async { - let share_dir = path::Path::new("shares") - .join(share); + let share_dir = path::Path::new("shares").join(share); if share_dir.exists() { let share_info = share_dir.join(".share.json"); @@ -50,17 +67,21 @@ impl FromRequest for Share where B: Send { } else { Ok::<_, color_eyre::Report>(None) } - }.await - .map_err(|e| { - tracing::error!(%e, "failed to load share info"); - StatusCode::INTERNAL_SERVER_ERROR - }) - .and_then(|share| share.ok_or(StatusCode::NOT_FOUND)) + } + .await + .map_err(|e| { + tracing::error!(%e, "failed to load share info"); + StatusCode::INTERNAL_SERVER_ERROR + }) + .and_then(|share| share.ok_or(StatusCode::NOT_FOUND)) } } async fn index(share: Share, tera: Renderer) -> impl IntoResponse { - tera.response("share/index.html", Context::from_serialize(&share.info).unwrap()) + tera.response( + "share/index.html", + Context::from_serialize(&share.info).unwrap(), + ) } #[derive(Deserialize)] @@ -68,21 +89,27 @@ struct RawPath { file_id: usize, } -async fn raw(share: Share, path: Path, req: Request) -> Result { +async fn raw( + share: Share, + path: Path, + req: Request, +) -> Result { if let Some(file) = share.info.files.get(path.file_id) { let path = share.path.join(file.name()); - ServeFile::new(path).call(req) - .await - .map_err(|e| { - tracing::error!(%e, "failed to serve static file"); - StatusCode::INTERNAL_SERVER_ERROR - }) + ServeFile::new(path).call(req).await.map_err(|e| { + tracing::error!(%e, "failed to serve static file"); + StatusCode::INTERNAL_SERVER_ERROR + }) } else { Err(StatusCode::NOT_FOUND) } } -async fn file(share: Share, path: Path, tera: Renderer) -> Result { +async fn file( + share: Share, + path: Path, + tera: Renderer, +) -> Result { if let Some(file) = share.info.files.get(path.file_id) { #[derive(Serialize)] struct File { @@ -93,11 +120,14 @@ async fn file(share: Share, path: Path, tera: Renderer) -> Result Result, StatusCode> { let result = self.render(name, &context); - result - .map(|rendered| Html(rendered)) - .map_err(|e| { - tracing::error!("failed to render template {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - }) + result.map(|rendered| Html(rendered)).map_err(|e| { + tracing::error!("failed to render template {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + }) } }