db improve data builder

This commit is contained in:
Dmitriy Pleshevskiy 2022-05-08 16:21:06 +03:00
parent bd8855fde6
commit 4d13485253
4 changed files with 186 additions and 111 deletions

View File

@ -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<fs::File>) -> 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<RecipeIngredient>,
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<RecipeTranslate>,
}
#[derive(Debug)]
pub struct RecipeTranslate {
name: &'static str,
instructions: Vec<&'static str>,
}
"#;
writeln!(file, "{}", structs)?;
Ok(())
}
#[derive(Deserialize, Debug)]
pub struct Main {
ingredients: Option<Vec<Ingredient>>,
@ -60,109 +130,49 @@ pub struct RecipeTranslate {
instructions: Vec<String>,
}
fn write_structs(file: &mut BufWriter<fs::File>) -> 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<RecipeIngredient>,")?;
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<RecipeTranslate>,")?;
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<fs::File>) -> 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::<String>()
)?;
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<Vec<Ingredient>, std::io::Error> {
Ok(fs::read_dir("data/ingredients")?
.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.ingredients)
.flatten()
.collect::<Vec<Ingredient>>())
}
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);
}
}

View File

@ -8,7 +8,7 @@ measure = "kg"
[[ingredients]]
key = "potato"
measure = "kg"
[ingredienst.translates]
[ingredients.translates]
ru = "картофель"
en = "potato"

View File

@ -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<RecipeTranslate>,
}
#[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"),
},
},
];

View File

@ -1,5 +1,3 @@
use crate::data::Ingredient;
mod data;
fn main() {