db: use debug instead of rewrite structs
This commit is contained in:
parent
4d13485253
commit
24e5f28e66
|
@ -6,10 +6,17 @@ version = 3
|
|||
name = "db"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.38"
|
||||
|
|
|
@ -8,3 +8,6 @@ edition = "2021"
|
|||
[build-dependencies]
|
||||
serde = { version = "1.0.137", features = ["derive"] }
|
||||
toml = "0.5.9"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
|
|
103
db/build.rs
103
db/build.rs
|
@ -1,10 +1,11 @@
|
|||
use core::fmt;
|
||||
use std::fs;
|
||||
use std::io::{BufWriter, Write};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-changed=data/*");
|
||||
if let Err(e) = gen_data_mod() {
|
||||
eprintln!("Error: {}", e);
|
||||
}
|
||||
|
@ -16,11 +17,14 @@ fn gen_data_mod() -> Result<(), std::io::Error> {
|
|||
write_structs(&mut buf)?;
|
||||
println!("cargo:rerun-if-changed=data/ingredients/*.toml");
|
||||
write_ingredients(&mut buf)?;
|
||||
println!("cargo:rerun-if-changed=data/recipes/*.toml");
|
||||
write_recipes(&mut buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_structs(file: &mut BufWriter<fs::File>) -> Result<(), std::io::Error> {
|
||||
let structs = r#"
|
||||
let structs = r#"#![allow(dead_code)]
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Ingredient {
|
||||
pub key: &'static str,
|
||||
|
@ -36,8 +40,8 @@ pub struct IngredientTranslate {
|
|||
#[derive(Debug)]
|
||||
pub struct Recipe {
|
||||
key: &'static str,
|
||||
ingredients: Vec<RecipeIngredient>,
|
||||
steps: u8,
|
||||
ingredients: Vec<RecipeIngredient>,
|
||||
translates: RecipeTranslates,
|
||||
}
|
||||
|
||||
|
@ -79,19 +83,21 @@ pub struct Main {
|
|||
recipes: Option<Vec<Recipe>>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Ingredient {
|
||||
key: String,
|
||||
translates: IngredientTranslate,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct IngredientTranslate {
|
||||
ru: String,
|
||||
en: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Recipe {
|
||||
key: String,
|
||||
ingredients: Vec<RecipeIngredient>,
|
||||
|
@ -99,13 +105,36 @@ pub struct Recipe {
|
|||
translates: RecipeTranslates,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
impl fmt::Debug for Recipe {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Recipe")
|
||||
.field("key", &self.key)
|
||||
.field("steps", &self.steps)
|
||||
.field("ingredients", &format_args!("vec!{:#?}", self.ingredients))
|
||||
.field("translates", &self.translates)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RecipeIngredient {
|
||||
key: String,
|
||||
#[serde(flatten)]
|
||||
measure: RecipeIngredientMeasure,
|
||||
}
|
||||
|
||||
impl fmt::Debug for RecipeIngredient {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RecipeIngredient")
|
||||
.field("key", &self.key)
|
||||
.field(
|
||||
"measure",
|
||||
&format_args!("RecipeIngredientMeasure::{:?}", self.measure),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub enum RecipeIngredientMeasure {
|
||||
#[serde(rename = "g")]
|
||||
|
@ -118,52 +147,44 @@ pub enum RecipeIngredientMeasure {
|
|||
Liter(u32),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct RecipeTranslates {
|
||||
ru: RecipeTranslate,
|
||||
en: Option<RecipeTranslate>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct RecipeTranslate {
|
||||
name: String,
|
||||
instructions: Vec<String>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for RecipeTranslate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RecipeTranslate")
|
||||
.field("name", &self.name)
|
||||
.field(
|
||||
"instructions",
|
||||
&format_args!("vec!{:#?}", self.instructions),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
fn write_ingredients(file: &mut BufWriter<fs::File>) -> Result<(), std::io::Error> {
|
||||
let ingredients = get_ingredient_configs()?;
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
"pub const INGREDIENTS: [Ingredient; {}] = [{}];",
|
||||
"pub const INGREDIENTS: [Ingredient; {}] = {:#?};\n",
|
||||
ingredients.len(),
|
||||
ingredients
|
||||
.into_iter()
|
||||
.map(|i| to_ingredient_data_content(1, i))
|
||||
.collect::<String>()
|
||||
)?;
|
||||
|
||||
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<Vec<Ingredient>, std::io::Error> {
|
||||
Ok(fs::read_dir("data/ingredients")?
|
||||
.map(|res| res.and_then(|e| fs::read_to_string(e.path())))
|
||||
|
@ -175,10 +196,28 @@ fn get_ingredient_configs() -> Result<Vec<Ingredient>, std::io::Error> {
|
|||
.collect::<Vec<Ingredient>>())
|
||||
}
|
||||
|
||||
fn indent(indent_size: usize) -> String {
|
||||
std::iter::repeat(" ").take(indent_size * 4).collect()
|
||||
fn write_recipes(file: &mut BufWriter<fs::File>) -> Result<(), std::io::Error> {
|
||||
let recipes = get_recipe_configs()?;
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#"lazy_static::lazy_static! {{
|
||||
pub static ref RECIPES: [Recipe; {}] = {:#?};
|
||||
}}"#,
|
||||
recipes.len(),
|
||||
recipes
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn to_str(string: String) -> &'static str {
|
||||
Box::leak(string.into_boxed_str())
|
||||
fn get_recipe_configs() -> Result<Vec<Recipe>, std::io::Error> {
|
||||
Ok(fs::read_dir("data/recipes")?
|
||||
.map(|res| res.and_then(|e| fs::read_to_string(e.path())))
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()?
|
||||
.into_iter()
|
||||
.map(|content| toml::from_str(&content).unwrap())
|
||||
.filter_map(|cfg: Main| cfg.recipes)
|
||||
.flatten()
|
||||
.collect::<Vec<Recipe>>())
|
||||
}
|
||||
|
|
107
db/src/data.rs
107
db/src/data.rs
|
@ -1,3 +1,4 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Ingredient {
|
||||
|
@ -14,8 +15,8 @@ pub struct IngredientTranslate {
|
|||
#[derive(Debug)]
|
||||
pub struct Recipe {
|
||||
key: &'static str,
|
||||
ingredients: Vec<RecipeIngredient>,
|
||||
steps: u8,
|
||||
ingredients: Vec<RecipeIngredient>,
|
||||
translates: RecipeTranslates,
|
||||
}
|
||||
|
||||
|
@ -50,87 +51,149 @@ pub const INGREDIENTS: [Ingredient; 11] = [
|
|||
key: "water",
|
||||
translates: IngredientTranslate {
|
||||
ru: "вода",
|
||||
en: Some("water"),
|
||||
en: Some(
|
||||
"water",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "carrot",
|
||||
translates: IngredientTranslate {
|
||||
ru: "морковь",
|
||||
en: Some("carrot"),
|
||||
en: Some(
|
||||
"carrot",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "potato",
|
||||
translates: IngredientTranslate {
|
||||
ru: "картофель",
|
||||
en: Some("potato"),
|
||||
en: Some(
|
||||
"potato",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "wheat_flour",
|
||||
translates: IngredientTranslate {
|
||||
ru: "пшеничная мука",
|
||||
en: Some("wheat flour"),
|
||||
en: Some(
|
||||
"wheat flour",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "olive_oil",
|
||||
translates: IngredientTranslate {
|
||||
ru: "оливковое масло",
|
||||
en: Some("olive oil"),
|
||||
en: Some(
|
||||
"olive oil",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "dry_yeast",
|
||||
translates: IngredientTranslate {
|
||||
ru: "сухие дрожжи",
|
||||
en: Some("dry yeast"),
|
||||
en: Some(
|
||||
"dry yeast",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "apple",
|
||||
translates: IngredientTranslate {
|
||||
ru: "яблоко",
|
||||
en: Some("apple"),
|
||||
en: Some(
|
||||
"apple",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "banana",
|
||||
translates: IngredientTranslate {
|
||||
ru: "банан",
|
||||
en: Some("banana"),
|
||||
en: Some(
|
||||
"banana",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "orange",
|
||||
translates: IngredientTranslate {
|
||||
ru: "апельсин",
|
||||
en: Some("orange"),
|
||||
en: Some(
|
||||
"orange",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "salt",
|
||||
translates: IngredientTranslate {
|
||||
ru: "соль",
|
||||
en: Some("salt"),
|
||||
en: Some(
|
||||
"salt",
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
Ingredient {
|
||||
key: "sugar",
|
||||
translates: IngredientTranslate {
|
||||
ru: "сахар",
|
||||
en: Some("sugar"),
|
||||
en: Some(
|
||||
"sugar",
|
||||
),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref RECIPES: [Recipe; 1] = [
|
||||
Recipe {
|
||||
key: "thin_crispy_pizza_base",
|
||||
steps: 7,
|
||||
ingredients: vec![
|
||||
RecipeIngredient {
|
||||
key: "salt",
|
||||
measure: RecipeIngredientMeasure::Gram(5),
|
||||
},
|
||||
RecipeIngredient {
|
||||
key: "sugar",
|
||||
measure: RecipeIngredientMeasure::Gram(4),
|
||||
},
|
||||
RecipeIngredient {
|
||||
key: "wheat_flour",
|
||||
measure: RecipeIngredientMeasure::Gram(500),
|
||||
},
|
||||
RecipeIngredient {
|
||||
key: "dry_yeast",
|
||||
measure: RecipeIngredientMeasure::Gram(7),
|
||||
},
|
||||
RecipeIngredient {
|
||||
key: "olive_oil",
|
||||
measure: RecipeIngredientMeasure::MilliLiter(25),
|
||||
},
|
||||
RecipeIngredient {
|
||||
key: "water",
|
||||
measure: RecipeIngredientMeasure::MilliLiter(250),
|
||||
},
|
||||
],
|
||||
translates: RecipeTranslates {
|
||||
ru: RecipeTranslate {
|
||||
name: "Тонкая хрустящая основа для пиццы",
|
||||
instructions: vec![
|
||||
"Растворить дрожжи в воде, подогретой до температуры тела.",
|
||||
"Добавить соль, сахар, оливковое масло и хорошо перемешать до однородной консистенции.",
|
||||
"Добавить муку и замесить тесто. Вымешивать не менее 15 минут.",
|
||||
"Разделить тесто на 3 порции, каждую завернуть в пищевую плёнку и дать настояться около 30 минут.",
|
||||
"Растянуть один кусок теста до тонкого состояния и аккуратно переложить на смазанный растительным маслом противень.",
|
||||
"Смазать соусом, чтобы тесто не осталось жидким и чтобы начинка не скользила по нему, и поставить в предварительно разогретую до максимальной температуры (не меньше 250 градусов) на 5-10 минут. В результате тесто хорошо пропечется и станет хрустящим.",
|
||||
"Теперь на основу можно выкладывать начинку на ваш вкус и запекать до момента, когда сыр растает.",
|
||||
],
|
||||
},
|
||||
en: None,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ mod data;
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
||||
dbg!(data::INGREDIENTS
|
||||
.into_iter()
|
||||
.filter(|i| i.key == "banana")
|
||||
.collect::<Vec<data::Ingredient>>());
|
||||
let banana = data::INGREDIENTS.into_iter().find(|i| i.key == "banana");
|
||||
dbg!(banana);
|
||||
|
||||
dbg!(data::RECIPES.iter().collect::<Vec<_>>());
|
||||
|
||||
// let cfg: config::Main = toml::from_str(include_str!("../data/ingredients/fruit.toml")).unwrap();
|
||||
// let cfg: config::Main = toml::from_str(include_str!("../data/recipes/pizza.toml")).unwrap();
|
||||
|
|
Loading…
Reference in New Issue