Skip to content

Commit e3acade

Browse files
committed
feat: Allow typed errors in category creation form
1 parent ae8d6de commit e3acade

3 files changed

Lines changed: 52 additions & 30 deletions

File tree

src/extractors/category_request.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ use crate::database::content_folder::PathBreadcrumb;
77
use crate::filesystem::FileSystemEntry;
88
use crate::state::{AppState, error::*};
99

10+
#[derive(Clone, Debug)]
11+
pub struct CategoriesRequest {
12+
pub children: Vec<FileSystemEntry>,
13+
}
14+
15+
impl FromRequestParts<AppState> for CategoriesRequest {
16+
type Rejection = AppStateError;
17+
18+
async fn from_request_parts(
19+
_parts: &mut Parts,
20+
app_state: &AppState,
21+
) -> Result<Self, Self::Rejection> {
22+
let categories = CategoryOperator::new(app_state.clone(), None)
23+
.list()
24+
.await
25+
.context(CategorySnafu)?;
26+
27+
let children = FileSystemEntry::from_categories(&categories);
28+
Ok(Self { children })
29+
}
30+
}
31+
1032
#[derive(Clone, Debug)]
1133
pub struct CategoryRequest {
1234
pub category: category::Model,

src/routes/category.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ use serde::{Deserialize, Serialize};
77

88
use crate::database::category;
99
use crate::database::content_folder::PathBreadcrumb;
10-
use crate::extractors::category_request::CategoryRequest;
10+
use crate::extractors::category_request::{CategoriesRequest, CategoryRequest};
1111
use crate::filesystem::FileSystemEntry;
1212
use crate::routes::content_folder::ContentFolderForm;
13+
use crate::routes::index::IndexTemplate;
1314
use crate::state::AppStateContext;
1415
use crate::state::flash_message::{
1516
FallibleTemplate, FlashRedirect, FlashTemplate, OperationStatus, StatusCookie,
@@ -55,21 +56,27 @@ pub async fn delete(
5556

5657
pub async fn create(
5758
context: AppStateContext,
59+
categories: CategoriesRequest,
5860
jar: CookieJar,
5961
Form(form): Form<CategoryForm>,
60-
) -> FlashRedirect {
61-
let status = match context.db.category().create(&form).await {
62-
Ok(created) => StatusCookie::success(
63-
jar,
64-
format!(
65-
"The category {} has been successfully created (ID {})",
66-
created.name, created.id
67-
),
68-
),
69-
Err(error) => StatusCookie::error(jar, error.to_string()),
70-
};
71-
72-
status.redirect("/")
62+
) -> Result<FlashRedirect, IndexTemplate> {
63+
match context.db.category().create(&form).await {
64+
Ok(created) => {
65+
let status = StatusCookie::success(
66+
jar,
67+
format!(
68+
"The category {} has been successfully created (ID {})",
69+
created.name, created.id
70+
),
71+
);
72+
let uri = format!("/folders/{}", created.name);
73+
Ok(status.redirect(&uri))
74+
}
75+
Err(error) => {
76+
let status = OperationStatus::error(error);
77+
Err(status.with_template(IndexTemplate::new(context, categories)))
78+
}
79+
}
7380
}
7481

7582
#[derive(Template, WebTemplate)]

src/routes/index.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use askama::Template;
22
use askama_web::WebTemplate;
3-
use snafu::prelude::*;
43

54
// TUTORIAL: https://github.com/SeaQL/sea-orm/blob/master/examples/axum_example/
5+
use crate::extractors::category_request::CategoriesRequest;
66
use crate::filesystem::FileSystemEntry;
7-
use crate::state::flash_message::{FallibleTemplate, FlashTemplate, OperationStatus, StatusCookie};
8-
use crate::state::{AppStateContext, error::*};
7+
use crate::state::AppStateContext;
8+
use crate::state::flash_message::{FallibleTemplate, OperationStatus};
99

1010
#[derive(Template, WebTemplate)]
1111
#[template(path = "index.html")]
@@ -25,22 +25,15 @@ impl FallibleTemplate for IndexTemplate {
2525
}
2626

2727
impl IndexTemplate {
28-
pub async fn new(context: AppStateContext) -> Result<Self, AppStateError> {
29-
let categories = context.db.category().list().await.context(CategorySnafu)?;
30-
let children = FileSystemEntry::from_categories(&categories);
31-
32-
Ok(Self {
28+
pub fn new(context: AppStateContext, categories: CategoriesRequest) -> Self {
29+
Self {
3330
state: context,
3431
flash: None,
35-
children,
36-
})
32+
children: categories.children,
33+
}
3734
}
3835
}
3936

40-
pub async fn index(
41-
context: AppStateContext,
42-
status: StatusCookie,
43-
) -> Result<FlashTemplate<IndexTemplate>, AppStateError> {
44-
let template = IndexTemplate::new(context).await?;
45-
Ok(status.with_template(template))
37+
pub async fn index(context: AppStateContext, categories: CategoriesRequest) -> IndexTemplate {
38+
IndexTemplate::new(context, categories)
4639
}

0 commit comments

Comments
 (0)