aboutsummaryrefslogtreecommitdiffstats
path: root/crates/rocie-server/src/storage/sql/get/recipe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rocie-server/src/storage/sql/get/recipe')
-rw-r--r--crates/rocie-server/src/storage/sql/get/recipe/mod.rs90
1 files changed, 74 insertions, 16 deletions
diff --git a/crates/rocie-server/src/storage/sql/get/recipe/mod.rs b/crates/rocie-server/src/storage/sql/get/recipe/mod.rs
index 9d6dc79..f433541 100644
--- a/crates/rocie-server/src/storage/sql/get/recipe/mod.rs
+++ b/crates/rocie-server/src/storage/sql/get/recipe/mod.rs
@@ -1,15 +1,38 @@
use crate::{
app::App,
- storage::sql::recipe::{Recipe, RecipeId},
+ storage::sql::{
+ recipe::{CooklangRecipe, Recipe, RecipeId},
+ recipe_parent::RecipeParentId,
+ },
};
use sqlx::query;
+pub(crate) mod parse {
+ use crate::storage::sql::recipe::conversion;
+
+ #[derive(thiserror::Error, Debug)]
+ pub(crate) enum Error {
+ #[error("Failed to convert from cooklang recipe to our own struct")]
+ Conversion(#[from] conversion::Error),
+ }
+}
+
+async fn recipe_from_content(app: &App, content: &str) -> Result<CooklangRecipe, parse::Error> {
+ // NOTE: We can ignore warnings here, as we should already have handled them at the recipe
+ // insert point. <2026-01-31>
+ let (output, _warnings) = cooklang::parse(content)
+ .into_result()
+ .expect("The values in the db should always be valid, as we checked before inserting them");
+
+ Ok(CooklangRecipe::from(app, output).await?)
+}
+
impl Recipe {
pub(crate) async fn from_id(app: &App, id: RecipeId) -> Result<Option<Self>, from_id::Error> {
let record = query!(
"
- SELECT content, path
+ SELECT name, parent, content
FROM recipies
WHERE id = ?
",
@@ -21,11 +44,33 @@ impl Recipe {
if let Some(record) = record {
Ok(Some(Self {
id,
- path: record
- .path
- .parse()
- .expect("Was a path before, should still be one"),
- content: record.content,
+ content: recipe_from_content(app, &record.content).await?,
+ name: record.name,
+ parent: record.parent.map(|id| RecipeParentId::from_db(&id)),
+ }))
+ } else {
+ Ok(None)
+ }
+ }
+
+ pub(crate) async fn from_name(app: &App, name: String) -> Result<Option<Self>, from_id::Error> {
+ let record = query!(
+ "
+ SELECT id, parent, content
+ FROM recipies
+ WHERE name = ?
+",
+ name
+ )
+ .fetch_optional(&app.db)
+ .await?;
+
+ if let Some(record) = record {
+ Ok(Some(Self {
+ id: RecipeId::from_db(&record.id),
+ content: recipe_from_content(app, &record.content).await?,
+ name,
+ parent: record.parent.map(|id| RecipeParentId::from_db(&id)),
}))
} else {
Ok(None)
@@ -35,31 +80,39 @@ impl Recipe {
pub(crate) async fn get_all(app: &App) -> Result<Vec<Self>, get_all::Error> {
let records = query!(
"
- SELECT id, content, path
+ SELECT id, name, parent, content
FROM recipies
",
)
.fetch_all(&app.db)
.await?;
- Ok(records
- .into_iter()
- .map(|record| Self {
+ let mut output = vec![];
+ for record in records {
+ output.push(Self {
id: RecipeId::from_db(&record.id),
- path: record.path.parse().expect("Is still valid"),
- content: record.content,
- })
- .collect())
+ content: recipe_from_content(app, &record.content).await?,
+ name: record.name,
+ parent: record.parent.map(|id| RecipeParentId::from_db(&id)),
+ });
+ }
+
+ Ok(output)
}
}
pub(crate) mod from_id {
use actix_web::ResponseError;
+ use crate::storage::sql::get::recipe::parse;
+
#[derive(thiserror::Error, Debug)]
pub(crate) enum Error {
- #[error("Failed to execute the sql query")]
+ #[error("Failed to execute the sql query: `{0}`")]
SqlError(#[from] sqlx::Error),
+
+ #[error("Failed to parse the recipe content as cooklang recipe: `{0}`")]
+ RecipeParse(#[from] parse::Error),
}
impl ResponseError for Error {}
@@ -68,10 +121,15 @@ pub(crate) mod from_id {
pub(crate) mod get_all {
use actix_web::ResponseError;
+ use crate::storage::sql::get::recipe::parse;
+
#[derive(thiserror::Error, Debug)]
pub(crate) enum Error {
#[error("Failed to execute the sql query")]
SqlError(#[from] sqlx::Error),
+
+ #[error("Failed to parse the recipe content as cooklang recipe")]
+ RecipeParse(#[from] parse::Error),
}
impl ResponseError for Error {}