From ee3271f77299e9602ccc8b669f6b8a685184d952 Mon Sep 17 00:00:00 2001 From: artus40 Date: Fri, 1 Feb 2019 21:35:47 +0100 Subject: [PATCH] Improves fields::RecipeCategory --- cookbook/db.sqlite3 | Bin 20480 -> 20480 bytes cookbook/src/bin/show_recipes.rs | 8 ++--- cookbook/src/bin/write_recipe.rs | 21 ++++++++++-- cookbook/src/models.rs | 55 ++++++++++++++++++++++--------- 4 files changed, 60 insertions(+), 24 deletions(-) diff --git a/cookbook/db.sqlite3 b/cookbook/db.sqlite3 index 6157cfa126d02589a208d68578d065f000992a82..bc86f9890b63179a13d953947aa64786275397a8 100644 GIT binary patch delta 185 zcmZozz}T>Wae_3X;zSu|M#YT@OY{ZU_;nfhAMx+!U&LR?AIz`2Sx`Wd-$jLujX{>t zoY%SN@QQ-eVqRwd)Y7zKUM{!9qRhNhUM`=+%o1KM8CEt1X-;k4;KZE7lvEhS1ywt_ z(0;NQCw~_M|0n+E{5Sc}@*m*ez`vM(I)4|?k^+7;Zcb(fS(u4j9Lx;TP@UZDKnbX! KT$4BW2LJ&1qA^JT delta 67 zcmZozz}T>Wae_3X%tRSyMwyKXOZ0hI_zM~MAMx+!U&LRySx_L6e{!MyWC1q*4GjFB X_@DFN(&conn) - .expect("Error loading recipes"); - - println!("Here are {} recipes :", result.len()); + let result = recipes::load_all(&conn); + println!("Here are {} recipes [{}]:", result.len(), result.len() * std::mem::size_of::()); for rec in result { println!("*************\n{}\n({:?})", rec.title, rec.category); println!("-------------\n"); diff --git a/cookbook/src/bin/write_recipe.rs b/cookbook/src/bin/write_recipe.rs index 31a18d5..d3e5900 100644 --- a/cookbook/src/bin/write_recipe.rs +++ b/cookbook/src/bin/write_recipe.rs @@ -27,6 +27,10 @@ impl<'a> CreateRecipe<'a> { self.title = title; } + fn set_category(&mut self, id: i16) { + self.category = RecipeCategory::from_id(id); + } + fn add_ingredient(&mut self, name: String) { use crate::ingredients::*; @@ -43,7 +47,11 @@ impl<'a> CreateRecipe<'a> { /// Builds a NewRecipe instance from current data and insert it. fn insert(self) { - let new_recipe = NewRecipe::new(self.title, 0, &self.ingredients, ""); + let new_recipe = NewRecipe::new( + self.title, + self.category.unwrap_or(RecipeCategory::Breakfast), + &self.ingredients, + ""); match new_recipe.insert(self.connection) { Ok(new) => println!("Added {}", new.title), Err(e) => println!("Error: {}", e), @@ -62,6 +70,15 @@ fn main() { let title = &title[..(title.len() - 1)]; builder.set_title(title); + println!("Category : "); + for cat in &RecipeCategory::all() { + println!("{} - {}", cat.id(), cat.name()); + } + let mut category_id = String::new(); + stdin().read_line(&mut category_id).unwrap(); + let category_id = category_id.trim().parse::().expect("Could not parse id"); + builder.set_category(category_id); + println!("Ingredients (empty line to finish): "); loop { let mut ingdts = String::new(); @@ -69,7 +86,7 @@ fn main() { if &ingdts == "\r\n" { break; } - builder.add_ingredient(ingdts.clone()); + builder.add_ingredient(ingdts); } builder.insert(); diff --git a/cookbook/src/models.rs b/cookbook/src/models.rs index 6066b8d..a430bb1 100644 --- a/cookbook/src/models.rs +++ b/cookbook/src/models.rs @@ -6,7 +6,7 @@ pub mod fields { use diesel::{ backend::Backend, sqlite::Sqlite, - sql_types::SmallInt, + sql_types::*, deserialize::{self, FromSql}, serialize::{self, Output, ToSql}, }; @@ -16,8 +16,8 @@ pub mod fields { /// representing the main use of the resulting preparation. /// /// It is stored as Integer - #[derive(Debug, Clone, FromSqlRow, AsExpression)] - #[repr(i16)] + #[derive(Debug, Copy, Clone, FromSqlRow, AsExpression)] + #[sql_type = "SmallInt"] pub enum RecipeCategory { Breakfast = 0, Starter = 1, @@ -26,7 +26,27 @@ pub mod fields { } impl RecipeCategory { - fn from_id(id: i16) -> Option { + 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 { match id { 0 => Some(RecipeCategory::Breakfast), 1 => Some(RecipeCategory::Starter), @@ -37,19 +57,22 @@ pub mod fields { } } - impl FromSql for RecipeCategory { - fn from_sql(bytes: Option<&::RawValue>) -> deserialize::Result { - if let Some(result) = RecipeCategory::from_id( - >::from_sql(bytes)?) - { Ok(result) } + impl FromSql for RecipeCategory + where + i16: FromSql + { + fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result { + let v = i16::from_sql(bytes)?; + if let Some(result) = RecipeCategory::from_id(v){ Ok(result) } else { Err("Invalid RecipeCategory id".into()) } } } - impl ToSql for RecipeCategory { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - let as_int = self.clone() as i16; - >::to_sql(&as_int, out) + impl ToSql for RecipeCategory + where + i16: ToSql{ + fn to_sql(&self, out: &mut Output) -> serialize::Result { + i16::to_sql(&(*self as i16), out) } } @@ -66,17 +89,17 @@ pub struct Recipe { pub preparation: String, } -#[derive(Insertable)] +#[derive(Insertable, Debug)] #[table_name="recipes"] pub struct NewRecipe<'a> { pub title: &'a str, - pub category: i16, + pub category: fields::RecipeCategory, pub ingredients: &'a str, pub preparation: &'a str, } impl<'a> NewRecipe<'a> { - pub fn new(title: &'a str, category: i16, ingredients: &'a str, preparation: &'a str) -> Self { + pub fn new(title: &'a str, category: fields::RecipeCategory, ingredients: &'a str, preparation: &'a str) -> Self { NewRecipe{ title, category,