Files
CookAssistant/cookbook/src/models.rs

130 lines
3.4 KiB
Rust

use super::schema::recipes;
use super::schema::ingredients;
use super::diesel::prelude::*;
pub mod fields {
use diesel::{
backend::Backend,
sql_types::*,
deserialize::{self, FromSql},
serialize::{self, Output, ToSql},
};
use std::io::Write;
/// All recipes have a single associated category
/// representing the main use of the resulting preparation.
///
/// It is stored as Integer
#[derive(Debug, Copy, Clone, FromSqlRow, AsExpression)]
#[sql_type = "SmallInt"]
pub enum RecipeCategory {
Breakfast = 0,
Starter = 1,
MainCourse = 2,
Dessert = 3
}
impl RecipeCategory {
pub fn id(&self) -> i16 {
*self as i16
}
pub fn name(&self) -> &str {
match *self {
RecipeCategory::Breakfast => "Petit-déjeuner",
RecipeCategory::Starter => "Entrée",
RecipeCategory::MainCourse => "Plat principal",
RecipeCategory::Dessert => "Dessert"
}
}
pub fn all() -> [Self; 4] {
[RecipeCategory::Breakfast,
RecipeCategory::Starter,
RecipeCategory::MainCourse,
RecipeCategory::Dessert]
}
pub fn from_id(id: i16) -> Option<RecipeCategory> {
match id {
0 => Some(RecipeCategory::Breakfast),
1 => Some(RecipeCategory::Starter),
2 => Some(RecipeCategory::MainCourse),
3 => Some(RecipeCategory::Dessert),
_ => None,
}
}
}
impl<DB: Backend> FromSql<SmallInt, DB> for RecipeCategory
where
i16: FromSql<SmallInt, DB>
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let v = i16::from_sql(bytes)?;
if let Some(result) = RecipeCategory::from_id(v){ Ok(result) }
else { Err("Invalid RecipeCategory id".into()) }
}
}
impl<DB: Backend> ToSql<SmallInt, DB> for RecipeCategory
where
i16: ToSql<SmallInt, DB>{
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
i16::to_sql(&(*self as i16), out)
}
}
}
/// Data for a recipe stored in DB
#[derive(Debug, Clone, Queryable)]
pub struct Recipe {
pub id: i32,
pub title: String,
pub category: fields::RecipeCategory,
pub ingredients: String,
pub preparation: String,
}
#[derive(Insertable, Debug)]
#[table_name="recipes"]
pub struct NewRecipe<'a> {
pub title: &'a str,
pub category: fields::RecipeCategory,
pub ingredients: &'a str,
pub preparation: &'a str,
}
impl<'a> NewRecipe<'a> {
pub fn new(title: &'a str, category: fields::RecipeCategory, ingredients: &'a str, preparation: &'a str) -> Self {
NewRecipe{
title,
category,
ingredients,
preparation,
}
}
pub fn insert(self, conn: &SqliteConnection) -> Result<Self, String> {
diesel::insert_into(recipes::table)
.values(&self)
.execute(conn)
.expect("Error inserting recipe");
Ok(self)
}
}
#[derive(Queryable)]
pub struct Ingredient {
pub id: i32,
pub alias: String,
}
#[derive(Insertable)]
#[table_name="ingredients"]
pub struct NewIngredient<'a> {
pub alias: &'a str,
}