todos more traits
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@@ -132,7 +132,6 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"axum-macros",
|
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@@ -175,18 +174,6 @@ dependencies = [
|
|||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "axum-macros"
|
|
||||||
version = "0.3.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62"
|
|
||||||
dependencies = [
|
|
||||||
"heck",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.35",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-prometheus"
|
name = "axum-prometheus"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ default = ["jaeger", "prometheus", "tokio-console"]
|
|||||||
opt-level = 0
|
opt-level = 0
|
||||||
lto = "off"
|
lto = "off"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
[dependencies.async-trait]
|
[dependencies.async-trait]
|
||||||
version = "0.1"
|
version = "0.1"
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ features = ["derive"]
|
|||||||
|
|
||||||
[dependencies.axum]
|
[dependencies.axum]
|
||||||
version = "0.6"
|
version = "0.6"
|
||||||
features = ["headers", "macros"]
|
features = ["headers"]
|
||||||
|
|
||||||
[dependencies.tokio]
|
[dependencies.tokio]
|
||||||
version = "1"
|
version = "1"
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ pub mod route {
|
|||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use axum::{
|
use axum::{
|
||||||
body::BoxBody,
|
body::BoxBody,
|
||||||
extract::{Path, State},
|
extract::{Path, Query, State},
|
||||||
http::HeaderMap,
|
http::HeaderMap,
|
||||||
response::Response,
|
response::Response,
|
||||||
Extension, Form,
|
Extension, Form,
|
||||||
@@ -128,7 +128,9 @@ pub mod route {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Create: super::crud::Create {
|
pub trait Create: super::crud::Create {
|
||||||
type FormX: Send + Sync + 'static;
|
type Form: Send + Sync + 'static;
|
||||||
|
|
||||||
|
type ParentUrlParams: Send + Sync + 'static;
|
||||||
type UrlParams: Send + Sync + 'static;
|
type UrlParams: Send + Sync + 'static;
|
||||||
|
|
||||||
const URL: &'static str;
|
const URL: &'static str;
|
||||||
@@ -137,8 +139,51 @@ pub mod route {
|
|||||||
user: Extension<crate::models::user::User>,
|
user: Extension<crate::models::user::User>,
|
||||||
state: State<AppState>,
|
state: State<AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
path: Path<Self::UrlParams>,
|
path: Path<(Self::ParentUrlParams, Self::UrlParams)>,
|
||||||
form: Form<Self::FormX>,
|
form: Form<Self::Form>,
|
||||||
) -> Result<Response<BoxBody>, crate::Error>;
|
) -> Result<Response<BoxBody>, crate::Error>;
|
||||||
|
|
||||||
|
fn with_prefix(prefix: &'static str) -> String {
|
||||||
|
format!("{}{}", prefix, Self::URL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait Read: super::crud::Read {
|
||||||
|
type UrlParams: Send + Sync + 'static;
|
||||||
|
type QueryParams: Send + Sync + 'static;
|
||||||
|
|
||||||
|
const URL: &'static str;
|
||||||
|
|
||||||
|
async fn read(
|
||||||
|
user: Extension<crate::models::user::User>,
|
||||||
|
state: State<AppState>,
|
||||||
|
headers: HeaderMap,
|
||||||
|
query: Query<Self::QueryParams>,
|
||||||
|
path: Path<Self::UrlParams>,
|
||||||
|
) -> Result<Response<BoxBody>, crate::Error>;
|
||||||
|
|
||||||
|
fn with_prefix(prefix: &'static str) -> String {
|
||||||
|
format!("{}{}", prefix, Self::URL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait Delete: super::crud::Delete {
|
||||||
|
type ParentUrlParams: Send + Sync + 'static;
|
||||||
|
type UrlParams: Send + Sync + 'static;
|
||||||
|
|
||||||
|
const URL: &'static str;
|
||||||
|
|
||||||
|
async fn delete(
|
||||||
|
user: Extension<crate::models::user::User>,
|
||||||
|
state: State<AppState>,
|
||||||
|
headers: HeaderMap,
|
||||||
|
path: Path<(Self::ParentUrlParams, Self::UrlParams)>,
|
||||||
|
) -> Result<Response<BoxBody>, crate::Error>;
|
||||||
|
|
||||||
|
fn with_prefix(prefix: &'static str) -> String {
|
||||||
|
format!("{}{}", prefix, Self::URL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -567,18 +567,19 @@ pub struct TripTodoNew {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl route::Create for Todo {
|
impl route::Create for Todo {
|
||||||
type FormX = TripTodoNew;
|
type Form = TripTodoNew;
|
||||||
type UrlParams = (Uuid,);
|
type ParentUrlParams = (Uuid,);
|
||||||
|
type UrlParams = ();
|
||||||
|
|
||||||
const URL: &'static str = "/:id/todo/new";
|
const URL: &'static str = "/new";
|
||||||
|
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
async fn create(
|
async fn create(
|
||||||
Extension(current_user): Extension<crate::models::user::User>,
|
Extension(current_user): Extension<crate::models::user::User>,
|
||||||
axum::extract::State(state): axum::extract::State<AppState>,
|
axum::extract::State(state): axum::extract::State<AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
Path((trip_id,)): Path<(Uuid,)>,
|
Path(((trip_id,), ())): Path<(Self::ParentUrlParams, Self::UrlParams)>,
|
||||||
Form(form): Form<TripTodoNew>,
|
Form(form): Form<Self::Form>,
|
||||||
) -> Result<Response<BoxBody>, crate::Error> {
|
) -> Result<Response<BoxBody>, crate::Error> {
|
||||||
let ctx = Context::build(current_user);
|
let ctx = Context::build(current_user);
|
||||||
// method output is not required as we reload the whole trip todos anyway
|
// method output is not required as we reload the whole trip todos anyway
|
||||||
@@ -614,6 +615,53 @@ impl route::Create for Todo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl route::Delete for Todo {
|
||||||
|
type ParentUrlParams = (Uuid,);
|
||||||
|
type UrlParams = (Uuid,);
|
||||||
|
|
||||||
|
const URL: &'static str = "/:id/delete";
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
|
async fn delete(
|
||||||
|
Extension(current_user): Extension<crate::models::user::User>,
|
||||||
|
axum::extract::State(state): axum::extract::State<AppState>,
|
||||||
|
_headers: HeaderMap,
|
||||||
|
Path(((trip_id,), (todo_id,))): Path<(Self::ParentUrlParams, Self::UrlParams)>,
|
||||||
|
) -> Result<Response<BoxBody>, crate::Error> {
|
||||||
|
let ctx = Context::build(current_user);
|
||||||
|
let deleted = <Self as crud::Delete>::delete(
|
||||||
|
&ctx,
|
||||||
|
&state.database_pool,
|
||||||
|
&TodoFilter { trip_id },
|
||||||
|
todo_id,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if !deleted {
|
||||||
|
return Err(crate::Error::Request(RequestError::NotFound {
|
||||||
|
message: format!("todo with id {todo_id} not found"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let trip = crate::models::trips::Trip::find(&ctx, &state.database_pool, trip_id).await?;
|
||||||
|
match trip {
|
||||||
|
None => Err(crate::Error::Request(RequestError::NotFound {
|
||||||
|
message: format!("trip with id {trip_id} not found"),
|
||||||
|
})),
|
||||||
|
Some(mut trip) => {
|
||||||
|
trip.load_todos(&ctx, &state.database_pool).await?;
|
||||||
|
Ok(TodoList {
|
||||||
|
trip: &trip,
|
||||||
|
todos: &trip.todos(),
|
||||||
|
}
|
||||||
|
.build(None)
|
||||||
|
.into_response())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct NewTodo;
|
pub struct NewTodo;
|
||||||
|
|
||||||
impl NewTodo {
|
impl NewTodo {
|
||||||
|
|||||||
@@ -152,10 +152,17 @@ pub fn router(state: AppState) -> Router {
|
|||||||
.route("/:id/todo/:id/edit/save", post(trip_todo_edit_save))
|
.route("/:id/todo/:id/edit/save", post(trip_todo_edit_save))
|
||||||
.route("/:id/todo/:id/edit/cancel", post(trip_todo_edit_cancel))
|
.route("/:id/todo/:id/edit/cancel", post(trip_todo_edit_cancel))
|
||||||
.route(
|
.route(
|
||||||
"/:id/todo/new",
|
&<crate::models::trips::todos::Todo as route::Create>::with_prefix(
|
||||||
|
"/:id/todo",
|
||||||
|
),
|
||||||
post(<crate::models::trips::todos::Todo as route::Create>::create),
|
post(<crate::models::trips::todos::Todo as route::Create>::create),
|
||||||
)
|
)
|
||||||
.route("/:id/todo/:id/delete", post(trip_todo_delete)),
|
.route(
|
||||||
|
&<crate::models::trips::todos::Todo as route::Delete>::with_prefix(
|
||||||
|
"/:id/todo",
|
||||||
|
),
|
||||||
|
post(<crate::models::trips::todos::Todo as route::Delete>::delete),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.nest(
|
.nest(
|
||||||
(&TopLevelPage::Inventory.path()).into(),
|
(&TopLevelPage::Inventory.path()).into(),
|
||||||
|
|||||||
@@ -1479,42 +1479,3 @@ pub async fn trip_todo_edit_cancel(
|
|||||||
.into_response()),
|
.into_response()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument]
|
|
||||||
pub async fn trip_todo_delete(
|
|
||||||
Extension(current_user): Extension<models::user::User>,
|
|
||||||
State(state): State<AppState>,
|
|
||||||
headers: HeaderMap,
|
|
||||||
Path((trip_id, todo_id)): Path<(Uuid, Uuid)>,
|
|
||||||
) -> Result<impl IntoResponse, Error> {
|
|
||||||
let ctx = Context::build(current_user);
|
|
||||||
let deleted = models::trips::todos::Todo::delete(
|
|
||||||
&ctx,
|
|
||||||
&state.database_pool,
|
|
||||||
&TodoFilter { trip_id },
|
|
||||||
todo_id,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !deleted {
|
|
||||||
return Err(Error::Request(RequestError::NotFound {
|
|
||||||
message: format!("todo with id {todo_id} not found"),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let trip = models::trips::Trip::find(&ctx, &state.database_pool, trip_id).await?;
|
|
||||||
match trip {
|
|
||||||
None => Err(Error::Request(RequestError::NotFound {
|
|
||||||
message: format!("trip with id {trip_id} not found"),
|
|
||||||
})),
|
|
||||||
Some(mut trip) => {
|
|
||||||
trip.load_todos(&ctx, &state.database_pool).await?;
|
|
||||||
Ok(models::trips::todos::TodoList {
|
|
||||||
trip: &trip,
|
|
||||||
todos: &trip.todos(),
|
|
||||||
}
|
|
||||||
.build(None)
|
|
||||||
.into_response())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user