Add parse recipe parts
This commit is contained in:
parent
afc77b5c3d
commit
a3a8e32f14
44
Cargo.lock
generated
44
Cargo.lock
generated
@ -1133,6 +1133,7 @@ dependencies = [
|
|||||||
"humantime",
|
"humantime",
|
||||||
"humantime-serde",
|
"humantime-serde",
|
||||||
"migration",
|
"migration",
|
||||||
|
"pulldown-cmark",
|
||||||
"redis 0.27.5",
|
"redis 0.27.5",
|
||||||
"rswind",
|
"rswind",
|
||||||
"rswind_cli",
|
"rswind_cli",
|
||||||
@ -1141,6 +1142,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"tantivy",
|
"tantivy",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tracing-test",
|
"tracing-test",
|
||||||
@ -1811,6 +1813,15 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getopts"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@ -3207,6 +3218,25 @@ dependencies = [
|
|||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"getopts",
|
||||||
|
"memchr",
|
||||||
|
"pulldown-cmark-escape",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark-escape"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
@ -4699,18 +4729,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.64"
|
version = "1.0.65"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.64"
|
version = "1.0.65"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -5022,6 +5052,12 @@ version = "1.12.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
@ -27,6 +27,8 @@ actix-session = { version = "0.10.1", features = ["redis-session-rustls"] }
|
|||||||
actix-identity = "0.8.0"
|
actix-identity = "0.8.0"
|
||||||
tantivy = "0.22.0"
|
tantivy = "0.22.0"
|
||||||
tempfile = "3.13.0"
|
tempfile = "3.13.0"
|
||||||
|
pulldown-cmark = "0.12.2"
|
||||||
|
thiserror = "1.0.65"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(iterator_try_collect)]
|
||||||
|
|
||||||
use actix::SyncArbiter;
|
use actix::SyncArbiter;
|
||||||
use actix_files::Files;
|
use actix_files::Files;
|
||||||
use actix_identity::IdentityMiddleware;
|
use actix_identity::IdentityMiddleware;
|
||||||
@ -13,6 +15,7 @@ pub mod entities;
|
|||||||
pub mod filters;
|
pub mod filters;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
const SESSION_KEY: &'static str = "session";
|
const SESSION_KEY: &'static str = "session";
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ struct SignInForm {
|
|||||||
page: Page,
|
page: Page,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Template)]
|
#[derive(Debug, Template, Deserialize, Clone)]
|
||||||
#[template(path = "recipies/create_form.jinja", ext = "html")]
|
#[template(path = "recipies/create_form.jinja", ext = "html")]
|
||||||
struct RecipeForm {
|
struct RecipeForm {
|
||||||
title: String,
|
title: String,
|
||||||
@ -293,6 +293,33 @@ async fn recipe_form(admin: Identity) -> RecipeForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/create")]
|
||||||
|
async fn create_recipe(
|
||||||
|
admin: Identity,
|
||||||
|
form: Form<RecipeForm>,
|
||||||
|
db: Data<DatabaseConnection>,
|
||||||
|
) -> RecipeForm {
|
||||||
|
let form = form.into_inner();
|
||||||
|
let mut failure = form.clone();
|
||||||
|
|
||||||
|
let title = form.title;
|
||||||
|
|
||||||
|
let mut summary = String::new();
|
||||||
|
let parser = pulldown_cmark::Parser::new(&form.summary);
|
||||||
|
pulldown_cmark::html::push_html(&mut summary, parser);
|
||||||
|
|
||||||
|
let Ok(steps) = crate::utils::parse_steps(&form.steps, 0) else {
|
||||||
|
failure.error = Some("Invalid steps list".into());
|
||||||
|
return failure;
|
||||||
|
};
|
||||||
|
let Ok(ingeredients) = crate::utils::parse_steps(&form.ingeredients, 0) else {
|
||||||
|
failure.error = Some("Invalid ingeredients list".into());
|
||||||
|
return failure;
|
||||||
|
};
|
||||||
|
|
||||||
|
failure
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/styles.css")]
|
#[get("/styles.css")]
|
||||||
async fn styles_css() -> HttpResponse {
|
async fn styles_css() -> HttpResponse {
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
@ -309,5 +336,6 @@ pub fn configure(config: &mut actix_web::web::ServiceConfig) {
|
|||||||
.service(show)
|
.service(show)
|
||||||
.service(search_page)
|
.service(search_page)
|
||||||
.service(search_results)
|
.service(search_results)
|
||||||
.service(recipe_form);
|
.service(recipe_form)
|
||||||
|
.service(create_recipe);
|
||||||
}
|
}
|
||||||
|
14
src/types.rs
14
src/types.rs
@ -1,8 +1,18 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub type User = String;
|
pub type User = String;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Invalid step list")]
|
||||||
|
InvalidStepList,
|
||||||
|
#[error("Invalid ingeredients list")]
|
||||||
|
InvalidIngeredientList,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
|
||||||
pub enum Page {
|
pub enum Page {
|
||||||
Index,
|
Index,
|
||||||
Recipe,
|
Recipe,
|
||||||
@ -10,7 +20,7 @@ pub enum Page {
|
|||||||
SignIn,
|
SignIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Admin {
|
pub struct Admin {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub pass: String,
|
pub pass: String,
|
||||||
|
68
src/utils.rs
Normal file
68
src/utils.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use crate::entities::recipe_ingeredients::ActiveModel as RIAM;
|
||||||
|
use crate::entities::recipe_steps::ActiveModel as RSAM;
|
||||||
|
use crate::types::Error::*;
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use sea_orm::ActivrValue::*;
|
||||||
|
|
||||||
|
pub fn parse_steps(s: &str, recipe_id: u64) -> Result<Vec<RSAM>, InvalidStepList> {
|
||||||
|
s.lines()
|
||||||
|
.filter(|s| !s.trim().is_empty())
|
||||||
|
.try_fold(Vec::new(), |mut v, line| {
|
||||||
|
let line = line.trim();
|
||||||
|
|
||||||
|
match line.chars().next() {
|
||||||
|
Some('*') => {
|
||||||
|
let line = line.replacen("*", "", 1).trim();
|
||||||
|
v.push(RSAM {
|
||||||
|
body: Set(line.to_string()),
|
||||||
|
recipe_id: Set(recipe_id),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Some('>') => {
|
||||||
|
let line = line.replacen(">", "", 1).trim();
|
||||||
|
v.last_mut().ok_or(InvalidStepList)?.hint = Set(line.to_string());
|
||||||
|
}
|
||||||
|
_ => return Err(InvalidStepList),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_ingenedients(s: &str, recipe_id: u64) -> Result<Vec<RIAM>, InvalidIngeredientList> {
|
||||||
|
s.lines()
|
||||||
|
.map(|s| s.trim())
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(|s| {
|
||||||
|
let mut pieces = s
|
||||||
|
.split_whitespace()
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
match pieces.len() {
|
||||||
|
0 | 1 => return Err(InvalidIngeredientList),
|
||||||
|
// no unit
|
||||||
|
2 => {
|
||||||
|
let qty = pieces.remove(0).parse().map_err(|_| InvalidIngeredientList);
|
||||||
|
Ok(RIAM {
|
||||||
|
recipe_id: Set(recipe_id),
|
||||||
|
name: Set(pieces.join(" ")),
|
||||||
|
qty: Set(qty),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let qty = pieces.remove(0).parse().map_err(|_| InvalidIngeredientList);
|
||||||
|
let unit = pieces.remove(0);
|
||||||
|
Ok(RIAM {
|
||||||
|
recipe_id: Set(recipe_id),
|
||||||
|
name: Set(pieces.join(" ")),
|
||||||
|
unit: Set(unit),
|
||||||
|
qty: Set(qty),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.try_collect()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user