diff --git a/.gitignore b/.gitignore index 625c3c1..aa64b5c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,6 @@ # database *.db - -# why sqlx? *.db-shm *.db-wal diff --git a/core/src/init.rs b/core/src/init.rs deleted file mode 100644 index 04cc472..0000000 --- a/core/src/init.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::fs::File; - -use log::LevelFilter; -use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger}; - -pub fn init() -> anyhow::Result<()> { - // init better_panic - better_panic::install(); - - // init logger - CombinedLogger::init(vec![ - TermLogger::new( - LevelFilter::Debug, - Config::default(), - TerminalMode::Mixed, - ColorChoice::Auto, - ), - WriteLogger::new( - LevelFilter::Info, - Config::default(), - File::create("logs.log").expect("create logs file"), - ), - ])?; - - Ok(()) -} diff --git a/core/src/main.rs b/core/src/main.rs index 12f2175..3cf1506 100644 --- a/core/src/main.rs +++ b/core/src/main.rs @@ -1,12 +1,14 @@ -mod init; - use homedisk_database::Database; -use homedisk_server::run_http_server; -use homedisk_types::config::types::Config; +use homedisk_server::serve_http; +use homedisk_types::config::Config; +/// Main function #[tokio::main] async fn main() -> anyhow::Result<()> { - init::init()?; + // init better_panic + better_panic::install(); + // init logger + init_logger()?; // parse config let config = Config::parse()?; @@ -22,6 +24,7 @@ async fn main() -> anyhow::Result<()> { .map(|e| e.parse().expect("parse CORS hosts")) .collect(); + // format host ip and port let host = format!( "{host}:{port}", host = config.http.host, @@ -29,7 +32,31 @@ async fn main() -> anyhow::Result<()> { ); // start http server - run_http_server(host, origins, db, config).await?; + serve_http(host, origins, db, config).await?; + + Ok(()) +} + +/// Init logger +fn init_logger() -> anyhow::Result<()> { + use std::fs::File; + + use log::LevelFilter; + use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger}; + + CombinedLogger::init(vec![ + TermLogger::new( + LevelFilter::Debug, + Config::default(), + TerminalMode::Mixed, + ColorChoice::Auto, + ), + WriteLogger::new( + LevelFilter::Info, + Config::default(), + File::create("logs.log").expect("create logs file"), + ), + ])?; Ok(()) } diff --git a/database/src/lib.rs b/database/src/lib.rs index 0f58ab5..7c09efe 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -1,6 +1,7 @@ -mod error; mod sqlite; -pub use error::*; +/// Imported from `homedisk_types::database::User`. pub use homedisk_types::database::User; +/// Imported from `homedisk_types::errors::DatabaseError`. +pub use homedisk_types::errors::DatabaseError as Error; pub use sqlite::*; diff --git a/database/src/sqlite.rs b/database/src/sqlite.rs index 551ccee..2f01635 100644 --- a/database/src/sqlite.rs +++ b/database/src/sqlite.rs @@ -4,9 +4,10 @@ use sqlx::{sqlite::SqliteQueryResult, Executor, Row, SqlitePool}; use super::{Error, User}; +/// SQL Database #[derive(Debug, Clone)] pub struct Database { - /// Sqlite Connection Pool + /// SQLite Connection Pool pub conn: SqlitePool, } @@ -15,7 +16,11 @@ impl Database { /// ```ignore,rust /// use homedisk_database::Database; /// + /// // open database in memory /// Database::open("sqlite::memory:").await?; + /// + /// // open database from file + /// Database::open("path/to/file.db").await?; /// ``` pub async fn open(path: &str) -> Result { debug!("Opening SQLite database"); @@ -29,7 +34,10 @@ impl Database { /// ```ignore,rust /// use homedisk_database::{Database, User}; /// + /// // create `User` type /// let user = User::new("username", "password"); + /// + /// // create a user in database /// db.create_user(&user).await?; /// ``` pub async fn create_user(&self, user: &User) -> Result { @@ -47,24 +55,32 @@ impl Database { /// ```ignore,rust /// use homedisk_database::{Database, User}; /// + /// // create `User` type /// let user = User::new("username", "password"); /// + /// // search for a user in database /// db.find_user(&user.username, &user.password).await?; /// ``` pub async fn find_user(&self, username: &str, password: &str) -> Result { debug!("Searching for a user - {}", username); + // create query request to database let query = sqlx::query_as::<_, User>("SELECT * FROM user WHERE username = ? AND password = ?") .bind(username) .bind(password); + // fetch query let mut stream = self.conn.fetch(query); + // get rows from query let row = stream.try_next().await?.ok_or(Error::UserNotFound)?; + // get `id` row let id = row.try_get("id")?; + // get `username` row let username = row.try_get("username")?; + // get `password` row let password = row.try_get("password")?; Ok(User { @@ -78,21 +94,29 @@ impl Database { /// ```ignore,rust /// use homedisk_database::{Database, User}; /// + /// // create `User` type /// let user = User::new("username", "password"); /// + /// // search for a user by UUID in database /// db.find_user_by_id(&user.id).await?; /// ``` pub async fn find_user_by_id(&self, id: String) -> Result { debug!("Searching for a user by UUID - {}", id); + // create query request to database let query = sqlx::query_as::<_, User>("SELECT * FROM user WHERE id = ?").bind(id); + // fetch query let mut stream = self.conn.fetch(query); + // get rows from query let row = stream.try_next().await?.ok_or(Error::UserNotFound)?; + // get `id` row let id = row.try_get("id")?; + // get `username` row let username = row.try_get("username")?; + // get `password` row let password = row.try_get("password")?; Ok(User { diff --git a/server/src/auth/login.rs b/server/src/auth/login.rs index 6526942..04155e4 100644 --- a/server/src/auth/login.rs +++ b/server/src/auth/login.rs @@ -2,7 +2,7 @@ use axum::{extract::rejection::JsonRejection, Extension, Json}; use homedisk_database::{Database, Error, User}; use homedisk_types::{ auth::login::{Request, Response}, - config::types::Config, + config::Config, errors::{AuthError, ServerError}, }; diff --git a/server/src/auth/register.rs b/server/src/auth/register.rs index 534207d..1aef688 100644 --- a/server/src/auth/register.rs +++ b/server/src/auth/register.rs @@ -4,12 +4,13 @@ use axum::{extract::rejection::JsonRejection, Extension, Json}; use homedisk_database::{Database, User}; use homedisk_types::{ auth::login::{Request, Response}, - config::types::Config, + config::Config, errors::{AuthError, ServerError}, }; use crate::middleware::{create_token, validate_json}; +/// Handle `/auth/register` requests pub async fn handle( Extension(db): Extension, Extension(config): Extension, diff --git a/server/src/auth/whoami.rs b/server/src/auth/whoami.rs index 9527fd0..d477462 100644 --- a/server/src/auth/whoami.rs +++ b/server/src/auth/whoami.rs @@ -3,7 +3,7 @@ use axum_auth::AuthBearer; use homedisk_database::{Database, Error}; use homedisk_types::{ auth::whoami::Response, - config::types::Config, + config::Config, errors::{AuthError, ServerError}, }; @@ -18,6 +18,7 @@ pub async fn handle( // validate user token let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?; + // search for a user in database let response = match db.find_user_by_id(token.claims.sub).await { Ok(res) => Response { username: res.username, diff --git a/server/src/error.rs b/server/src/error.rs index 1c405b7..3d333cb 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -1,29 +1,35 @@ +// HTTP Error #[derive(Debug, thiserror::Error)] pub enum Error { + // axum::Error #[error("axum error - {0}")] Axum(axum::Error), - + // hyper::Error #[error("hyper error - {0}")] Hyper(hyper::Error), - + // std::net::AddrParseError #[error("std::net::AddrParseError - {0}")] AddrParseError(std::net::AddrParseError), } +/// Custom Result pub type Result = std::result::Result; +/// axum::Error impl From for Error { fn from(err: axum::Error) -> Self { Error::Axum(err) } } +/// hyper::Error impl From for Error { fn from(err: hyper::Error) -> Self { Error::Hyper(err) } } +/// std::net::AddrParseError impl From for Error { fn from(err: std::net::AddrParseError) -> Self { Error::AddrParseError(err) diff --git a/server/src/fs/create_dir.rs b/server/src/fs/create_dir.rs index fc683b9..6485475 100644 --- a/server/src/fs/create_dir.rs +++ b/server/src/fs/create_dir.rs @@ -5,13 +5,14 @@ use axum_auth::AuthBearer; use homedisk_database::Database; use homedisk_types::fs::create_dir::{Request, Response}; use homedisk_types::{ - config::types::Config, + config::Config, errors::{FsError, ServerError}, }; use crate::fs::validate_path; use crate::middleware::{find_user, validate_json, validate_jwt}; +/// Handle `/fs/createdir` requests pub async fn handle( Extension(db): Extension, Extension(config): Extension, diff --git a/server/src/fs/delete.rs b/server/src/fs/delete.rs index 79d8070..f78cc1e 100644 --- a/server/src/fs/delete.rs +++ b/server/src/fs/delete.rs @@ -5,7 +5,7 @@ use axum::Extension; use axum_auth::AuthBearer; use homedisk_database::Database; use homedisk_types::{ - config::types::Config, + config::Config, errors::{FsError, ServerError}, fs::delete::Request, }; diff --git a/server/src/fs/download.rs b/server/src/fs/download.rs index 786e899..3b96ffc 100644 --- a/server/src/fs/download.rs +++ b/server/src/fs/download.rs @@ -6,10 +6,11 @@ use axum::Extension; use axum_auth::AuthBearer; use homedisk_database::Database; use homedisk_types::fs::upload::Pagination; -use homedisk_types::{config::types::Config, errors::ServerError}; +use homedisk_types::{config::Config, errors::ServerError}; use crate::middleware::{find_user, validate_jwt}; +/// Handle `/fs/download` requests pub async fn handle( Extension(db): Extension, Extension(config): Extension, diff --git a/server/src/fs/list.rs b/server/src/fs/list.rs index 086de55..5817962 100644 --- a/server/src/fs/list.rs +++ b/server/src/fs/list.rs @@ -8,7 +8,7 @@ use byte_unit::Byte; use homedisk_database::Database; use homedisk_types::fs::list::DirInfo; use homedisk_types::{ - config::types::Config, + config::Config, errors::{FsError, ServerError}, fs::list::{FileInfo, Request, Response}, }; diff --git a/server/src/fs/upload.rs b/server/src/fs/upload.rs index ea45991..38ce37a 100644 --- a/server/src/fs/upload.rs +++ b/server/src/fs/upload.rs @@ -7,7 +7,7 @@ use axum_auth::AuthBearer; use futures::TryStreamExt; use homedisk_database::Database; use homedisk_types::{ - config::types::Config, + config::Config, errors::{FsError, ServerError}, fs::upload::{Pagination, Response}, }; @@ -15,6 +15,7 @@ use homedisk_types::{ use crate::fs::validate_path; use crate::middleware::{find_user, validate_jwt}; +/// Handle `/fs/upload` requests pub async fn handle( Extension(db): Extension, Extension(config): Extension, diff --git a/server/src/lib.rs b/server/src/lib.rs index f462848..e876dc2 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,12 +1,11 @@ -pub mod auth; -pub mod fs; -pub mod middleware; - +mod auth; mod error; +mod fs; +mod middleware; use axum::{http::HeaderValue, routing::get, Extension, Router, Server}; use homedisk_database::Database; -use homedisk_types::config::types::Config; +use homedisk_types::config::Config; use log::{debug, info}; use tower_http::cors::{AllowOrigin, CorsLayer}; @@ -15,7 +14,8 @@ async fn health_check() -> &'static str { "I'm alive!" } -pub async fn run_http_server( +/// Start HTTP server +pub async fn serve_http( host: String, origins: Vec, db: Database, diff --git a/types/src/auth/login.rs b/types/src/auth/login.rs index e13bb41..3cde15d 100644 --- a/types/src/auth/login.rs +++ b/types/src/auth/login.rs @@ -1,3 +1,5 @@ +//! `/auth/login` Request and Response types + use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/types/src/auth/mod.rs b/types/src/auth/mod.rs index 1e2917a..6ccd5d1 100644 --- a/types/src/auth/mod.rs +++ b/types/src/auth/mod.rs @@ -1,2 +1,4 @@ +//! HTTP `/auth/*` types for Request and Response + pub mod login; pub mod whoami; diff --git a/types/src/auth/whoami.rs b/types/src/auth/whoami.rs index 9335599..5767494 100644 --- a/types/src/auth/whoami.rs +++ b/types/src/auth/whoami.rs @@ -1,3 +1,5 @@ +//! `/auth/whoami` Response type + use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/types/src/config/mod.rs b/types/src/config/mod.rs index 09cfeab..d4dbbe9 100644 --- a/types/src/config/mod.rs +++ b/types/src/config/mod.rs @@ -1,4 +1,7 @@ -pub mod types; +//! Types for configuration file #[cfg(feature = "config")] -pub mod toml; +mod toml; +mod types; + +pub use types::*; diff --git a/types/src/config/toml.rs b/types/src/config/toml.rs index 3e6876c..44bde65 100644 --- a/types/src/config/toml.rs +++ b/types/src/config/toml.rs @@ -8,6 +8,11 @@ use super::types::Config; impl Config { /// Parse configuration file + /// ``` + /// use homedisk_types::config::Config; + /// + /// let config = Config::parse().unwrap(); + /// ``` pub fn parse() -> Result { // config file path let config_dir = option_return!(dirs::config_dir(), "get config dir")?; diff --git a/types/src/config/types.rs b/types/src/config/types.rs index 2b161a5..7cf0380 100644 --- a/types/src/config/types.rs +++ b/types/src/config/types.rs @@ -1,5 +1,8 @@ +//! Configuration file types + use serde::{Deserialize, Serialize}; +/// Config type #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { pub http: ConfigHTTP, @@ -7,6 +10,7 @@ pub struct Config { pub storage: ConfigStorage, } +/// HTTP config #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConfigHTTP { /// HTTP Host @@ -17,6 +21,7 @@ pub struct ConfigHTTP { pub cors: Vec, } +/// Json Web Token config #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConfigJWT { /// JWT Secret string @@ -25,6 +30,7 @@ pub struct ConfigJWT { pub expires: i64, } +/// Storage config #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConfigStorage { /// Directory where user files will be stored diff --git a/types/src/database/mod.rs b/types/src/database/mod.rs index 2478900..4aa1e3b 100644 --- a/types/src/database/mod.rs +++ b/types/src/database/mod.rs @@ -1,3 +1,5 @@ +//! Typed for a database + mod user; pub use user::*; diff --git a/types/src/database/user.rs b/types/src/database/user.rs index 22db9e8..afc1308 100644 --- a/types/src/database/user.rs +++ b/types/src/database/user.rs @@ -1,7 +1,7 @@ use rust_utilities::crypto::sha::{encode, Algorithm, CryptographicHash}; use uuid::Uuid; -/// SQL `user` Table +/// SQL user table #[derive(Debug, sqlx::FromRow)] pub struct User { pub id: String, @@ -53,12 +53,14 @@ impl User { /// assert_eq!(dir, "/home/homedisk/medzik") /// ``` pub fn user_dir(&self, storage: &str) -> String { + // get a user storage path let path = format!( "{path}/{username}", path = storage, username = self.username, ); + // return user storage path path } } diff --git a/types/src/errors/auth.rs b/types/src/errors/auth.rs index 0d79961..4ea0c67 100644 --- a/types/src/errors/auth.rs +++ b/types/src/errors/auth.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; +/// `/auth/*` Error #[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] pub enum Error { #[error("user not found")] diff --git a/database/src/error.rs b/types/src/errors/database.rs similarity index 78% rename from database/src/error.rs rename to types/src/errors/database.rs index 5f24532..c963992 100644 --- a/database/src/error.rs +++ b/types/src/errors/database.rs @@ -1,13 +1,14 @@ +/// Database Error #[derive(Debug, thiserror::Error)] pub enum Error { #[error("user not found")] UserNotFound, - + /// sqlx::Error #[error("sqlx error - {0}")] SQLx(sqlx::Error), - + /// std::io::Error #[error("std::io error - {0}")] - Io(std::io::Error), + StdIo(std::io::Error), } /// sqlx::Error @@ -20,6 +21,6 @@ impl From for Error { /// std::io::Error impl From for Error { fn from(err: std::io::Error) -> Self { - Error::Io(err) + Error::StdIo(err) } } diff --git a/types/src/errors/fs.rs b/types/src/errors/fs.rs index 343886d..01bd2b0 100644 --- a/types/src/errors/fs.rs +++ b/types/src/errors/fs.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; +/// `/fs/*` Error #[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] pub enum Error { #[error("file already exists")] diff --git a/types/src/errors/mod.rs b/types/src/errors/mod.rs index 3ce5e9d..99fe940 100644 --- a/types/src/errors/mod.rs +++ b/types/src/errors/mod.rs @@ -1,79 +1,12 @@ +//! Error types + mod auth; +#[cfg(feature = "database")] +mod database; mod fs; +mod server; pub use auth::Error as AuthError; +pub use database::Error as DatabaseError; pub use fs::Error as FsError; - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] -#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")] -pub enum ServerError { - #[error("auth error: {0}")] - AuthError(#[from] AuthError), - - #[error("fs error: {0}")] - FsError(#[from] FsError), - - #[error("too may requests, please slow down")] - TooManyRequests, - - #[error("missing json content type")] - MissingJsonContentType, - - #[error("error deserialize json")] - JsonDataError, - - #[error("json syntax error")] - JsonSyntaxError, - - #[error("failed to extract the request body")] - BytesRejection, - - #[error("unexpected error - {0}")] - Other(String), -} - -#[cfg(feature = "axum")] -impl axum::response::IntoResponse for ServerError { - fn into_response(self) -> axum::response::Response { - use axum::http::StatusCode; - - let status = match self { - Self::AuthError(ref err) => match err { - AuthError::UserNotFound => StatusCode::BAD_REQUEST, - AuthError::UserAlreadyExists => StatusCode::NOT_ACCEPTABLE, - AuthError::UsernameTooShort => StatusCode::NOT_ACCEPTABLE, - AuthError::UsernameTooLong => StatusCode::NOT_ACCEPTABLE, - AuthError::PasswordTooShort => StatusCode::NOT_ACCEPTABLE, - AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR, - AuthError::InvalidToken => StatusCode::BAD_REQUEST, - AuthError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR, - }, - Self::FsError(ref err) => match err { - FsError::FileAlreadyExists => StatusCode::BAD_REQUEST, - FsError::FileDoesNotExist => StatusCode::BAD_REQUEST, - FsError::MultipartError => StatusCode::BAD_REQUEST, - FsError::CreateFile(_) => StatusCode::INTERNAL_SERVER_ERROR, - FsError::CreateDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR, - FsError::DeleteFile(_) => StatusCode::INTERNAL_SERVER_ERROR, - FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR, - FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR, - FsError::Base64(_) => StatusCode::BAD_REQUEST, - FsError::ReadDir(_) => StatusCode::BAD_REQUEST, - FsError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR, - }, - Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS, - Self::MissingJsonContentType => StatusCode::BAD_REQUEST, - Self::JsonDataError => StatusCode::BAD_REQUEST, - Self::JsonSyntaxError => StatusCode::BAD_REQUEST, - Self::BytesRejection => StatusCode::INTERNAL_SERVER_ERROR, - Self::Other(_) => StatusCode::INTERNAL_SERVER_ERROR, - }; - - let mut response = axum::Json(self).into_response(); - *response.status_mut() = status; - - response - } -} +pub use server::Error as ServerError; diff --git a/types/src/errors/server.rs b/types/src/errors/server.rs new file mode 100644 index 0000000..f81fc2d --- /dev/null +++ b/types/src/errors/server.rs @@ -0,0 +1,76 @@ +use serde::{Deserialize, Serialize}; + +use super::{AuthError, FsError}; + +/// HTTP Server Error +#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] +#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")] +pub enum Error { + #[error("auth error: {0}")] + AuthError(#[from] AuthError), + + #[error("fs error: {0}")] + FsError(#[from] FsError), + + #[error("too may requests, please slow down")] + TooManyRequests, + + #[error("missing json content type")] + MissingJsonContentType, + + #[error("error deserialize json")] + JsonDataError, + + #[error("json syntax error")] + JsonSyntaxError, + + #[error("failed to extract the request body")] + BytesRejection, + + #[error("unexpected error - {0}")] + Other(String), +} + +#[cfg(feature = "axum")] +impl axum::response::IntoResponse for Error { + fn into_response(self) -> axum::response::Response { + use axum::http::StatusCode; + + let status = match self { + Self::AuthError(ref err) => match err { + AuthError::UserNotFound => StatusCode::BAD_REQUEST, + AuthError::UserAlreadyExists => StatusCode::NOT_ACCEPTABLE, + AuthError::UsernameTooShort => StatusCode::NOT_ACCEPTABLE, + AuthError::UsernameTooLong => StatusCode::NOT_ACCEPTABLE, + AuthError::PasswordTooShort => StatusCode::NOT_ACCEPTABLE, + AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR, + AuthError::InvalidToken => StatusCode::BAD_REQUEST, + AuthError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR, + }, + Self::FsError(ref err) => match err { + FsError::FileAlreadyExists => StatusCode::BAD_REQUEST, + FsError::FileDoesNotExist => StatusCode::BAD_REQUEST, + FsError::MultipartError => StatusCode::BAD_REQUEST, + FsError::CreateFile(_) => StatusCode::INTERNAL_SERVER_ERROR, + FsError::CreateDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR, + FsError::DeleteFile(_) => StatusCode::INTERNAL_SERVER_ERROR, + FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR, + FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR, + FsError::Base64(_) => StatusCode::BAD_REQUEST, + FsError::ReadDir(_) => StatusCode::BAD_REQUEST, + FsError::UnknownError(_) => StatusCode::INTERNAL_SERVER_ERROR, + }, + Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS, + Self::MissingJsonContentType => StatusCode::BAD_REQUEST, + Self::JsonDataError => StatusCode::BAD_REQUEST, + Self::JsonSyntaxError => StatusCode::BAD_REQUEST, + Self::BytesRejection => StatusCode::INTERNAL_SERVER_ERROR, + Self::Other(_) => StatusCode::INTERNAL_SERVER_ERROR, + }; + + let mut response = axum::Json(self).into_response(); + *response.status_mut() = status; + + response + } +} diff --git a/types/src/fs/mod.rs b/types/src/fs/mod.rs index 94a5e57..8cc9156 100644 --- a/types/src/fs/mod.rs +++ b/types/src/fs/mod.rs @@ -1,3 +1,5 @@ +//! HTTP `/fs/*` types for Request and Response + pub mod create_dir; pub mod delete; pub mod download; diff --git a/types/src/lib.rs b/types/src/lib.rs index d422234..c30b5c0 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -4,4 +4,5 @@ pub mod config; pub mod database; pub mod errors; pub mod fs; -pub mod macros; + +mod macros; diff --git a/types/src/macros.rs b/types/src/macros.rs index 3d20e4b..4885351 100644 --- a/types/src/macros.rs +++ b/types/src/macros.rs @@ -1,3 +1,4 @@ +/// Return value or error (if None) from Some(T) #[macro_export] macro_rules! option_return { ($variable:expr,$err_desc:expr) => {