adds Key generic parameters, use custom Key type from template.rs
This commit is contained in:
@@ -1,117 +1,35 @@
|
||||
//! The weekly menu planner
|
||||
//!
|
||||
extern crate cookbook;
|
||||
extern crate planner;
|
||||
extern crate cookbook;
|
||||
|
||||
use self::cookbook::*;
|
||||
use self::cookbook::recipes::Recipe;
|
||||
use self::planner::solver::{Variables, Domain, Problem};
|
||||
|
||||
type DomainValues<'a, V> = Vec<&'a V>;
|
||||
/// We want a mapping of the week meals (matin, midi, soir)
|
||||
/// Breakfast => RecipeCategory::Breakfast
|
||||
/// Lunch => RecipeCategory::MainCourse
|
||||
/// Dinner => RecipeCategory::MainCourse
|
||||
|
||||
mod template {
|
||||
//! Exports the [`Template`] struct.
|
||||
use super::{Domain, DomainValues, Variables, Recipe};
|
||||
|
||||
type Day = String;
|
||||
const DAYS: &[&str] = &[
|
||||
"Lundi", "Mardi", "Mercredi",
|
||||
"Jeudi", "Vendredi", "Samedi",
|
||||
"Dimanche"];
|
||||
|
||||
/// An enum to discriminate every meals
|
||||
#[allow(dead_code)]
|
||||
pub enum Meals {
|
||||
Breakfast(Day),
|
||||
Lunch(Day),
|
||||
Dinner(Day)
|
||||
}
|
||||
|
||||
impl From<Meals> for String {
|
||||
fn from(item: Meals) -> String {
|
||||
match item {
|
||||
Meals::Breakfast(d) => format!("{}_Breakfast", d),
|
||||
Meals::Lunch(d) => format!("{}_Lunch", d),
|
||||
Meals::Dinner(d) => format!("{}_Dinner", d),
|
||||
}
|
||||
}
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::Display;
|
||||
use std::hash::Hash;
|
||||
use cookbook::*;
|
||||
use planner::{
|
||||
*, Value,
|
||||
solver::{
|
||||
Variables,
|
||||
Domain,
|
||||
Problem
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// A fixed template of meals
|
||||
///
|
||||
/// TODO: mask -> disabled choosen meals
|
||||
/// initials -> fixed values
|
||||
pub struct Template;
|
||||
|
||||
impl Template {
|
||||
|
||||
fn keys() -> Vec<Meals> {
|
||||
let mut keys = Vec::new();
|
||||
for day in DAYS {
|
||||
for meal in &[Meals::Breakfast, Meals::Lunch, Meals::Dinner] {
|
||||
keys.push(meal(day.to_string()))
|
||||
}
|
||||
}
|
||||
keys
|
||||
}
|
||||
|
||||
/// Build a [`Template`] from a variables assignment map,
|
||||
/// usually a solution returned by solver
|
||||
pub(super) fn from_variables<'a, V>(_vars: Variables<'a,V>) -> Template{
|
||||
Template
|
||||
}
|
||||
|
||||
/// Builds a vector of variables, to be used with
|
||||
/// [`ProblemBuilder`].
|
||||
pub(super) fn generate_variables(domain: &Domain<Recipe>)
|
||||
-> Vec<(String, DomainValues<Recipe>, Option<&Recipe>)>
|
||||
{
|
||||
use cookbook::recipes::RecipeCategory;
|
||||
let mut vars = Vec::new();
|
||||
for key in Self::keys().into_iter() {
|
||||
//TODO: Use key variants to set filters on domain
|
||||
//TODO: Initial values
|
||||
let _filter: fn(&&Recipe) -> bool = match key {
|
||||
Meals::Breakfast(_) => |r: &&Recipe| {
|
||||
r.category == RecipeCategory::Breakfast // Breakfast
|
||||
},
|
||||
Meals::Lunch(_) => |r: &&Recipe| {
|
||||
r.category as i16 == 2i16 // MainCourse
|
||||
},
|
||||
Meals::Dinner(_) => |r: &&Recipe| {
|
||||
r.category as i16 == 1i16 // Starter
|
||||
}
|
||||
};
|
||||
vars.push((key.into(), domain.filter(_filter), None));
|
||||
}
|
||||
vars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ingredients_contains<'a>(_assign: &Variables<'a,Recipe>) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
fn pretty_output(res: &Variables<Recipe>) -> String {
|
||||
fn pretty_output<K: Eq + Hash + Debug>(res: &Variables<Value, K>) -> String {
|
||||
let mut repr = String::new();
|
||||
for (var,value) in res {
|
||||
let value = match value {
|
||||
Some(rec) => &rec.title,
|
||||
None => "---",
|
||||
};
|
||||
repr.push_str(&format!("{} => {}\n", var, value));
|
||||
repr.push_str(&format!("{:?} => {}\n", var, value));
|
||||
}
|
||||
repr
|
||||
}
|
||||
|
||||
fn get_planning_all_results() -> String {
|
||||
fn main() {
|
||||
let conn = establish_connection();
|
||||
let possible_values = recipes::load_all(&conn);
|
||||
let domain = Domain::new(possible_values);
|
||||
@@ -119,15 +37,7 @@ fn get_planning_all_results() -> String {
|
||||
for (var, dom, ini) in template::Template::generate_variables(&domain) {
|
||||
problem = problem.add_variable(var, dom, ini);
|
||||
}
|
||||
let mut problem = problem
|
||||
.add_constraint(
|
||||
ingredients_contains
|
||||
)
|
||||
.finish();
|
||||
let mut problem = problem.finish();
|
||||
let results = problem.solve_all();
|
||||
format!("{}\nTotal = {}", pretty_output(&results.first().unwrap()), results.len())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", get_planning_all_results());
|
||||
println!("{:?}", pretty_output(results.first().unwrap()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user