From 4d13485253de030a52a9a317d3fe5e8904a760b9 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 8 May 2022 16:21:06 +0300 Subject: [PATCH] db improve data builder --- db/build.rs | 205 +++++++++++++++-------------- db/data/ingredients/vegetable.toml | 2 +- db/src/data.rs | 88 ++++++++++++- db/src/main.rs | 2 - 4 files changed, 186 insertions(+), 111 deletions(-) diff --git a/db/build.rs b/db/build.rs index 2109b2d..7fc94bc 100644 --- a/db/build.rs +++ b/db/build.rs @@ -3,6 +3,76 @@ use std::io::{BufWriter, Write}; use serde::Deserialize; +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + if let Err(e) = gen_data_mod() { + eprintln!("Error: {}", e); + } +} + +fn gen_data_mod() -> Result<(), std::io::Error> { + let file = fs::File::create("src/data.rs")?; + let mut buf = BufWriter::new(file); + write_structs(&mut buf)?; + println!("cargo:rerun-if-changed=data/ingredients/*.toml"); + write_ingredients(&mut buf)?; + Ok(()) +} + +fn write_structs(file: &mut BufWriter) -> Result<(), std::io::Error> { + let structs = r#" +#[derive(Debug)] +pub struct Ingredient { + pub key: &'static str, + pub translates: IngredientTranslate, +} + +#[derive(Debug)] +pub struct IngredientTranslate { + pub ru: &'static str, + pub en: Option<&'static str>, +} + +#[derive(Debug)] +pub struct Recipe { + key: &'static str, + ingredients: Vec, + steps: u8, + translates: RecipeTranslates, +} + +#[derive(Debug)] +pub struct RecipeIngredient { + key: &'static str, + measure: RecipeIngredientMeasure, +} + +#[derive(Debug)] +pub enum RecipeIngredientMeasure { + Gram(u32), + KiloGram(u32), + MilliLiter(u32), + Liter(u32), +} + +#[derive(Debug)] +pub struct RecipeTranslates { + ru: RecipeTranslate, + en: Option, +} + +#[derive(Debug)] +pub struct RecipeTranslate { + name: &'static str, + instructions: Vec<&'static str>, +} +"#; + + writeln!(file, "{}", structs)?; + + Ok(()) +} + #[derive(Deserialize, Debug)] pub struct Main { ingredients: Option>, @@ -60,109 +130,49 @@ pub struct RecipeTranslate { instructions: Vec, } -fn write_structs(file: &mut BufWriter) -> Result<(), std::io::Error> { - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct Ingredient {{")?; - writeln!(file, " pub key: &'static str,")?; - writeln!(file, " translates: IngredientTranslate,")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct IngredientTranslate {{")?; - writeln!(file, " ru: &'static str,")?; - writeln!(file, " en: Option<&'static str>,")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct Recipe {{")?; - writeln!(file, " key: &'static str,")?; - writeln!(file, " ingredients: Vec,")?; - writeln!(file, " steps: u8,")?; - writeln!(file, " translates: RecipeTranslates,")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct RecipeIngredient {{")?; - writeln!(file, " key: &'static str,")?; - writeln!(file, " measure: RecipeIngredientMeasure,")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub enum RecipeIngredientMeasure {{")?; - writeln!(file, " Gram(u32),")?; - writeln!(file, " KiloGram(u32),")?; - writeln!(file, " MilliLiter(u32),")?; - writeln!(file, " Liter(u32),")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct RecipeTranslates {{")?; - writeln!(file, " ru: RecipeTranslate,")?; - writeln!(file, " en: Option,")?; - writeln!(file, "}}")?; - - writeln!(file, "#[derive(Debug)]")?; - writeln!(file, "pub struct RecipeTranslate {{")?; - writeln!(file, " name: &'static str,")?; - writeln!(file, " instructions: Vec<&'static str>,")?; - writeln!(file, "}}")?; - Ok(()) -} - fn write_ingredients(file: &mut BufWriter) -> Result<(), std::io::Error> { - // fs::read_dir("data/ingredients") - let fruit = fs::read_to_string("data/ingredients/fruit.toml")?; - let cfg: Main = toml::from_str(&fruit).unwrap(); - - let mut ins: usize = 0; + let ingredients = get_ingredient_configs()?; writeln!( file, - "pub const INGREDIENTS: [Ingredient; {}] = [", - cfg.ingredients - .as_ref() - .map(|i| i.len()) - .unwrap_or_default() + "pub const INGREDIENTS: [Ingredient; {}] = [{}];", + ingredients.len(), + ingredients + .into_iter() + .map(|i| to_ingredient_data_content(1, i)) + .collect::() )?; - ins += 1; - if let Some(ingredients) = cfg.ingredients { - for ingredient in ingredients { - writeln!(file, "{}Ingredient {{", indent(ins))?; - ins += 1; - writeln!(file, "{}key: {:?},", indent(ins), to_str(ingredient.key))?; - writeln!(file, "{}translates: IngredientTranslate {{", indent(ins))?; - ins += 1; - writeln!( - file, - "{}ru: {:?},", - indent(ins), - to_str(ingredient.translates.ru) - )?; - writeln!( - file, - "{}en: {:?},", - indent(ins), - ingredient.translates.en.map(to_str) - )?; - ins -= 1; - writeln!(file, "{}}}", indent(ins))?; - ins -= 1; - writeln!(file, "{}}},", indent(ins))?; - } - } - ins -= 1; - writeln!(file, "{}];", indent(ins))?; Ok(()) } -fn gen_data_mod() -> Result<(), std::io::Error> { - let file = fs::File::create("src/data.rs")?; - let mut buf = BufWriter::new(file); - write_structs(&mut buf)?; - println!("cargo:rerun-if-changed=data"); - write_ingredients(&mut buf)?; - Ok(()) +fn to_ingredient_data_content(indent_size: usize, ingredient: Ingredient) -> String { + format!( + r#" +{i}Ingredient {{ +{i} key: {key:?}, +{i} translates: IngredientTranslate {{ +{i} ru: {tr_ru:?}, +{i} en: {tr_en:?}, +{i} }}, +{i}}}, +"#, + i = indent(indent_size), + key = to_str(ingredient.key), + tr_ru = to_str(ingredient.translates.ru), + tr_en = ingredient.translates.en.map(to_str), + ) +} + +fn get_ingredient_configs() -> Result, std::io::Error> { + Ok(fs::read_dir("data/ingredients")? + .map(|res| res.and_then(|e| fs::read_to_string(e.path()))) + .collect::, std::io::Error>>()? + .into_iter() + .map(|content| toml::from_str(&content).unwrap()) + .filter_map(|cfg: Main| cfg.ingredients) + .flatten() + .collect::>()) } fn indent(indent_size: usize) -> String { @@ -172,10 +182,3 @@ fn indent(indent_size: usize) -> String { fn to_str(string: String) -> &'static str { Box::leak(string.into_boxed_str()) } - -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - if let Err(e) = gen_data_mod() { - eprintln!("Error: {}", e); - } -} diff --git a/db/data/ingredients/vegetable.toml b/db/data/ingredients/vegetable.toml index 84344f3..7710009 100644 --- a/db/data/ingredients/vegetable.toml +++ b/db/data/ingredients/vegetable.toml @@ -8,7 +8,7 @@ measure = "kg" [[ingredients]] key = "potato" measure = "kg" - [ingredienst.translates] + [ingredients.translates] ru = "картофель" en = "potato" diff --git a/db/src/data.rs b/db/src/data.rs index 51fbbf2..36d9c3f 100644 --- a/db/src/data.rs +++ b/db/src/data.rs @@ -1,13 +1,16 @@ + #[derive(Debug)] pub struct Ingredient { pub key: &'static str, - translates: IngredientTranslate, + pub translates: IngredientTranslate, } + #[derive(Debug)] pub struct IngredientTranslate { - ru: &'static str, - en: Option<&'static str>, + pub ru: &'static str, + pub en: Option<&'static str>, } + #[derive(Debug)] pub struct Recipe { key: &'static str, @@ -15,11 +18,13 @@ pub struct Recipe { steps: u8, translates: RecipeTranslates, } + #[derive(Debug)] pub struct RecipeIngredient { key: &'static str, measure: RecipeIngredientMeasure, } + #[derive(Debug)] pub enum RecipeIngredientMeasure { Gram(u32), @@ -27,36 +32,105 @@ pub enum RecipeIngredientMeasure { MilliLiter(u32), Liter(u32), } + #[derive(Debug)] pub struct RecipeTranslates { ru: RecipeTranslate, en: Option, } + #[derive(Debug)] pub struct RecipeTranslate { name: &'static str, instructions: Vec<&'static str>, } -pub const INGREDIENTS: [Ingredient; 3] = [ + +pub const INGREDIENTS: [Ingredient; 11] = [ + Ingredient { + key: "water", + translates: IngredientTranslate { + ru: "вода", + en: Some("water"), + }, + }, + + Ingredient { + key: "carrot", + translates: IngredientTranslate { + ru: "морковь", + en: Some("carrot"), + }, + }, + + Ingredient { + key: "potato", + translates: IngredientTranslate { + ru: "картофель", + en: Some("potato"), + }, + }, + + Ingredient { + key: "wheat_flour", + translates: IngredientTranslate { + ru: "пшеничная мука", + en: Some("wheat flour"), + }, + }, + + Ingredient { + key: "olive_oil", + translates: IngredientTranslate { + ru: "оливковое масло", + en: Some("olive oil"), + }, + }, + + Ingredient { + key: "dry_yeast", + translates: IngredientTranslate { + ru: "сухие дрожжи", + en: Some("dry yeast"), + }, + }, + Ingredient { key: "apple", translates: IngredientTranslate { ru: "яблоко", en: Some("apple"), - } + }, }, + Ingredient { key: "banana", translates: IngredientTranslate { ru: "банан", en: Some("banana"), - } + }, }, + Ingredient { key: "orange", translates: IngredientTranslate { ru: "апельсин", en: Some("orange"), - } + }, + }, + + Ingredient { + key: "salt", + translates: IngredientTranslate { + ru: "соль", + en: Some("salt"), + }, + }, + + Ingredient { + key: "sugar", + translates: IngredientTranslate { + ru: "сахар", + en: Some("sugar"), + }, }, ]; diff --git a/db/src/main.rs b/db/src/main.rs index 7ae3ee3..279e23d 100644 --- a/db/src/main.rs +++ b/db/src/main.rs @@ -1,5 +1,3 @@ -use crate::data::Ingredient; - mod data; fn main() {