182 lines
5.0 KiB
Rust
182 lines
5.0 KiB
Rust
use std::fs;
|
|
use std::io::{BufWriter, Write};
|
|
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct Main {
|
|
ingredients: Option<Vec<Ingredient>>,
|
|
recipes: Option<Vec<Recipe>>,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct Ingredient {
|
|
key: String,
|
|
translates: IngredientTranslate,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct IngredientTranslate {
|
|
ru: String,
|
|
en: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct Recipe {
|
|
key: String,
|
|
ingredients: Vec<RecipeIngredient>,
|
|
steps: u8,
|
|
translates: RecipeTranslates,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct RecipeIngredient {
|
|
key: String,
|
|
#[serde(flatten)]
|
|
measure: RecipeIngredientMeasure,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub enum RecipeIngredientMeasure {
|
|
#[serde(rename = "g")]
|
|
Gram(u32),
|
|
#[serde(rename = "kg")]
|
|
KiloGram(u32),
|
|
#[serde(rename = "ml")]
|
|
MilliLiter(u32),
|
|
#[serde(rename = "l")]
|
|
Liter(u32),
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct RecipeTranslates {
|
|
ru: RecipeTranslate,
|
|
en: Option<RecipeTranslate>,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct RecipeTranslate {
|
|
name: String,
|
|
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;
|
|
|
|
writeln!(
|
|
file,
|
|
"pub const INGREDIENTS: [Ingredient; {}] = [",
|
|
cfg.ingredients
|
|
.as_ref()
|
|
.map(|i| i.len())
|
|
.unwrap_or_default()
|
|
)?;
|
|
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 indent(indent_size: usize) -> String {
|
|
std::iter::repeat(" ").take(indent_size * 4).collect()
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|