diff options
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/handlers/asset.rs | 7 | ||||
| -rw-r--r-- | src/ui/handlers/channel.rs | 58 | ||||
| -rw-r--r-- | src/ui/handlers/index.rs (renamed from src/ui/routes/get.rs) | 0 | ||||
| -rw-r--r-- | src/ui/handlers/invite.rs | 53 | ||||
| -rw-r--r-- | src/ui/handlers/login.rs | 8 | ||||
| -rw-r--r-- | src/ui/handlers/me.rs | 30 | ||||
| -rw-r--r-- | src/ui/handlers/mod.rs | 15 | ||||
| -rw-r--r-- | src/ui/handlers/setup.rs | 41 | ||||
| -rw-r--r-- | src/ui/mod.rs | 4 | ||||
| -rw-r--r-- | src/ui/routes/ch/channel.rs | 60 | ||||
| -rw-r--r-- | src/ui/routes/ch/mod.rs | 1 | ||||
| -rw-r--r-- | src/ui/routes/invite/invite.rs | 55 | ||||
| -rw-r--r-- | src/ui/routes/invite/mod.rs | 4 | ||||
| -rw-r--r-- | src/ui/routes/login.rs | 10 | ||||
| -rw-r--r-- | src/ui/routes/me.rs | 32 | ||||
| -rw-r--r-- | src/ui/routes/mod.rs | 28 | ||||
| -rw-r--r-- | src/ui/routes/path.rs | 9 | ||||
| -rw-r--r-- | src/ui/routes/setup.rs | 43 |
18 files changed, 213 insertions, 245 deletions
diff --git a/src/ui/handlers/asset.rs b/src/ui/handlers/asset.rs new file mode 100644 index 0000000..1d5b8be --- /dev/null +++ b/src/ui/handlers/asset.rs @@ -0,0 +1,7 @@ +use axum::extract::Path; + +use crate::ui::assets::{Asset, Assets, Error}; + +pub async fn handler(Path(path): Path<String>) -> Result<Asset, Error> { + Assets::load(path) +} diff --git a/src/ui/handlers/channel.rs b/src/ui/handlers/channel.rs new file mode 100644 index 0000000..d3199dd --- /dev/null +++ b/src/ui/handlers/channel.rs @@ -0,0 +1,58 @@ +use axum::{ + extract::{Path, State}, + response::{self, IntoResponse, Redirect}, +}; + +use crate::{ + app::App, + channel::{self, app}, + error::Internal, + token::extract::Identity, + ui::{ + assets::{Asset, Assets}, + error::NotFound, + }, +}; + +pub async fn handler( + State(app): State<App>, + identity: Option<Identity>, + Path(channel): Path<channel::Id>, +) -> Result<Asset, Error> { + let _ = identity.ok_or(Error::NotLoggedIn)?; + app.channels().get(&channel).await.map_err(Error::from)?; + + Assets::index().map_err(Error::Internal) +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("channel not found")] + NotFound, + #[error("not logged in")] + NotLoggedIn, + #[error("{0}")] + Internal(Internal), +} + +impl From<app::Error> for Error { + fn from(error: app::Error) -> Self { + match error { + app::Error::NotFound(_) | app::Error::Deleted(_) => Self::NotFound, + other => Self::Internal(other.into()), + } + } +} + +impl IntoResponse for Error { + fn into_response(self) -> response::Response { + match self { + Self::NotFound => match Assets::index() { + Ok(asset) => NotFound(asset).into_response(), + Err(internal) => internal.into_response(), + }, + Self::NotLoggedIn => Redirect::temporary("/login").into_response(), + Self::Internal(error) => error.into_response(), + } + } +} diff --git a/src/ui/routes/get.rs b/src/ui/handlers/index.rs index 2fcb51c..2fcb51c 100644 --- a/src/ui/routes/get.rs +++ b/src/ui/handlers/index.rs diff --git a/src/ui/handlers/invite.rs b/src/ui/handlers/invite.rs new file mode 100644 index 0000000..0f9580a --- /dev/null +++ b/src/ui/handlers/invite.rs @@ -0,0 +1,53 @@ +use axum::{ + extract::{Path, State}, + response::{self, IntoResponse}, +}; + +use crate::{ + app::App, + error::Internal, + invite, + ui::{ + assets::{Asset, Assets}, + error::NotFound, + }, +}; + +pub async fn handler( + State(app): State<App>, + Path(invite): Path<invite::Id>, +) -> Result<Asset, Error> { + app.invites() + .get(&invite) + .await + .map_err(Error::internal)? + .ok_or(Error::NotFound)?; + + Assets::index().map_err(Error::Internal) +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("invite not found")] + NotFound, + #[error("{0}")] + Internal(Internal), +} + +impl Error { + fn internal(err: impl Into<Internal>) -> Self { + Self::Internal(err.into()) + } +} + +impl IntoResponse for Error { + fn into_response(self) -> response::Response { + match self { + Self::NotFound => match Assets::index() { + Ok(asset) => NotFound(asset).into_response(), + Err(internal) => internal.into_response(), + }, + Self::Internal(error) => error.into_response(), + } + } +} diff --git a/src/ui/handlers/login.rs b/src/ui/handlers/login.rs new file mode 100644 index 0000000..4562b04 --- /dev/null +++ b/src/ui/handlers/login.rs @@ -0,0 +1,8 @@ +use crate::{ + error::Internal, + ui::assets::{Asset, Assets}, +}; + +pub async fn handler() -> Result<Asset, Internal> { + Assets::index() +} diff --git a/src/ui/handlers/me.rs b/src/ui/handlers/me.rs new file mode 100644 index 0000000..2fcb51c --- /dev/null +++ b/src/ui/handlers/me.rs @@ -0,0 +1,30 @@ +use axum::response::{self, IntoResponse, Redirect}; + +use crate::{ + error::Internal, + token::extract::Identity, + ui::assets::{Asset, Assets}, +}; + +pub async fn handler(identity: Option<Identity>) -> Result<Asset, Error> { + let _ = identity.ok_or(Error::NotLoggedIn)?; + + Assets::index().map_err(Error::Internal) +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("not logged in")] + NotLoggedIn, + #[error("{0}")] + Internal(Internal), +} + +impl IntoResponse for Error { + fn into_response(self) -> response::Response { + match self { + Self::NotLoggedIn => Redirect::temporary("/login").into_response(), + Self::Internal(error) => error.into_response(), + } + } +} diff --git a/src/ui/handlers/mod.rs b/src/ui/handlers/mod.rs new file mode 100644 index 0000000..5bfd0d6 --- /dev/null +++ b/src/ui/handlers/mod.rs @@ -0,0 +1,15 @@ +mod asset; +mod channel; +mod index; +mod invite; +mod login; +mod me; +mod setup; + +pub use asset::handler as asset; +pub use channel::handler as channel; +pub use index::handler as index; +pub use invite::handler as invite; +pub use login::handler as login; +pub use me::handler as me; +pub use setup::handler as setup; diff --git a/src/ui/handlers/setup.rs b/src/ui/handlers/setup.rs new file mode 100644 index 0000000..49821cf --- /dev/null +++ b/src/ui/handlers/setup.rs @@ -0,0 +1,41 @@ +use axum::{ + extract::State, + response::{self, IntoResponse, Redirect}, +}; + +use crate::{ + app::App, + error::Internal, + ui::assets::{Asset, Assets}, +}; + +pub async fn handler(State(app): State<App>) -> Result<Asset, Error> { + if app + .setup() + .completed() + .await + .map_err(Internal::from) + .map_err(Error::Internal)? + { + Err(Error::SetupCompleted) + } else { + Assets::index().map_err(Error::Internal) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("setup already completed")] + SetupCompleted, + #[error("{0}")] + Internal(Internal), +} + +impl IntoResponse for Error { + fn into_response(self) -> response::Response { + match self { + Self::SetupCompleted => Redirect::to("/login").into_response(), + Self::Internal(error) => error.into_response(), + } + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index e834bba..9668300 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,6 +1,4 @@ mod assets; mod error; +pub mod handlers; mod mime; -mod routes; - -pub use self::routes::router; diff --git a/src/ui/routes/ch/channel.rs b/src/ui/routes/ch/channel.rs deleted file mode 100644 index a854f14..0000000 --- a/src/ui/routes/ch/channel.rs +++ /dev/null @@ -1,60 +0,0 @@ -pub mod get { - use axum::{ - extract::{Path, State}, - response::{self, IntoResponse, Redirect}, - }; - - use crate::{ - app::App, - channel::{self, app}, - error::Internal, - token::extract::Identity, - ui::{ - assets::{Asset, Assets}, - error::NotFound, - }, - }; - - pub async fn handler( - State(app): State<App>, - identity: Option<Identity>, - Path(channel): Path<channel::Id>, - ) -> Result<Asset, Error> { - let _ = identity.ok_or(Error::NotLoggedIn)?; - app.channels().get(&channel).await.map_err(Error::from)?; - - Assets::index().map_err(Error::Internal) - } - - #[derive(Debug, thiserror::Error)] - pub enum Error { - #[error("channel not found")] - NotFound, - #[error("not logged in")] - NotLoggedIn, - #[error("{0}")] - Internal(Internal), - } - - impl From<app::Error> for Error { - fn from(error: app::Error) -> Self { - match error { - app::Error::NotFound(_) | app::Error::Deleted(_) => Self::NotFound, - other => Self::Internal(other.into()), - } - } - } - - impl IntoResponse for Error { - fn into_response(self) -> response::Response { - match self { - Self::NotFound => match Assets::index() { - Ok(asset) => NotFound(asset).into_response(), - Err(internal) => internal.into_response(), - }, - Self::NotLoggedIn => Redirect::temporary("/login").into_response(), - Self::Internal(error) => error.into_response(), - } - } - } -} diff --git a/src/ui/routes/ch/mod.rs b/src/ui/routes/ch/mod.rs deleted file mode 100644 index ff02972..0000000 --- a/src/ui/routes/ch/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod channel; diff --git a/src/ui/routes/invite/invite.rs b/src/ui/routes/invite/invite.rs deleted file mode 100644 index 06e5792..0000000 --- a/src/ui/routes/invite/invite.rs +++ /dev/null @@ -1,55 +0,0 @@ -pub mod get { - use axum::{ - extract::{Path, State}, - response::{self, IntoResponse}, - }; - - use crate::{ - app::App, - error::Internal, - invite, - ui::{ - assets::{Asset, Assets}, - error::NotFound, - }, - }; - - pub async fn handler( - State(app): State<App>, - Path(invite): Path<invite::Id>, - ) -> Result<Asset, Error> { - app.invites() - .get(&invite) - .await - .map_err(Error::internal)? - .ok_or(Error::NotFound)?; - - Assets::index().map_err(Error::Internal) - } - - #[derive(Debug, thiserror::Error)] - pub enum Error { - #[error("invite not found")] - NotFound, - #[error("{0}")] - Internal(Internal), - } - - impl Error { - fn internal(err: impl Into<Internal>) -> Self { - Self::Internal(err.into()) - } - } - - impl IntoResponse for Error { - fn into_response(self) -> response::Response { - match self { - Self::NotFound => match Assets::index() { - Ok(asset) => NotFound(asset).into_response(), - Err(internal) => internal.into_response(), - }, - Self::Internal(error) => error.into_response(), - } - } - } -} diff --git a/src/ui/routes/invite/mod.rs b/src/ui/routes/invite/mod.rs deleted file mode 100644 index 50af8be..0000000 --- a/src/ui/routes/invite/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -// In this case, the first redundant `invite` is a literal path segment, and the -// second `invite` reflects a placeholder. -#[allow(clippy::module_inception)] -pub mod invite; diff --git a/src/ui/routes/login.rs b/src/ui/routes/login.rs deleted file mode 100644 index 39d45b9..0000000 --- a/src/ui/routes/login.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod get { - use crate::{ - error::Internal, - ui::assets::{Asset, Assets}, - }; - - pub async fn handler() -> Result<Asset, Internal> { - Assets::index() - } -} diff --git a/src/ui/routes/me.rs b/src/ui/routes/me.rs deleted file mode 100644 index f1f118f..0000000 --- a/src/ui/routes/me.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub mod get { - use axum::response::{self, IntoResponse, Redirect}; - - use crate::{ - error::Internal, - token::extract::Identity, - ui::assets::{Asset, Assets}, - }; - - pub async fn handler(identity: Option<Identity>) -> Result<Asset, Error> { - let _ = identity.ok_or(Error::NotLoggedIn)?; - - Assets::index().map_err(Error::Internal) - } - - #[derive(Debug, thiserror::Error)] - pub enum Error { - #[error("not logged in")] - NotLoggedIn, - #[error("{0}")] - Internal(Internal), - } - - impl IntoResponse for Error { - fn into_response(self) -> response::Response { - match self { - Self::NotLoggedIn => Redirect::temporary("/login").into_response(), - Self::Internal(error) => error.into_response(), - } - } - } -} diff --git a/src/ui/routes/mod.rs b/src/ui/routes/mod.rs deleted file mode 100644 index dc94773..0000000 --- a/src/ui/routes/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -use axum::{Router, response::Redirect, routing::get}; - -use crate::app::App; - -mod ch; -mod get; -mod invite; -mod login; -mod me; -mod path; -mod setup; - -pub fn router(app: &App) -> Router<App> { - [ - Router::new() - .route("/{*path}", get(path::get::handler)) - .route("/setup", get(setup::get::handler)), - Router::new() - .route("/", get(get::handler)) - .route("/me", get(me::get::handler)) - .route("/login", get(login::get::handler)) - .route("/ch/{channel}", get(ch::channel::get::handler)) - .route("/invite/{invite}", get(invite::invite::get::handler)) - .route_layer(crate::setup::Required(app.clone()).with_fallback(Redirect::to("/setup"))), - ] - .into_iter() - .fold(Router::default(), Router::merge) -} diff --git a/src/ui/routes/path.rs b/src/ui/routes/path.rs deleted file mode 100644 index a387552..0000000 --- a/src/ui/routes/path.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod get { - use axum::extract::Path; - - use crate::ui::assets::{Asset, Assets, Error}; - - pub async fn handler(Path(path): Path<String>) -> Result<Asset, Error> { - Assets::load(path) - } -} diff --git a/src/ui/routes/setup.rs b/src/ui/routes/setup.rs deleted file mode 100644 index 649cc5f..0000000 --- a/src/ui/routes/setup.rs +++ /dev/null @@ -1,43 +0,0 @@ -pub mod get { - use axum::{ - extract::State, - response::{self, IntoResponse, Redirect}, - }; - - use crate::{ - app::App, - error::Internal, - ui::assets::{Asset, Assets}, - }; - - pub async fn handler(State(app): State<App>) -> Result<Asset, Error> { - if app - .setup() - .completed() - .await - .map_err(Internal::from) - .map_err(Error::Internal)? - { - Err(Error::SetupCompleted) - } else { - Assets::index().map_err(Error::Internal) - } - } - - #[derive(Debug, thiserror::Error)] - pub enum Error { - #[error("setup already completed")] - SetupCompleted, - #[error("{0}")] - Internal(Internal), - } - - impl IntoResponse for Error { - fn into_response(self) -> response::Response { - match self { - Self::SetupCompleted => Redirect::to("/login").into_response(), - Self::Internal(error) => error.into_response(), - } - } - } -} |
