Skip to content

Instantly share code, notes, and snippets.

@williammartin
Last active August 13, 2020 16:04
Show Gist options
  • Select an option

  • Save williammartin/43b4766bcb2fef83d2e6585bd7ea5e51 to your computer and use it in GitHub Desktop.

Select an option

Save williammartin/43b4766bcb2fef83d2e6585bd7ea5e51 to your computer and use it in GitHub Desktop.
#[derive(Debug, PartialEq)]
pub enum Material {
Brick,
Concrete,
Wood,
}
#[derive(Debug, PartialEq)]
pub struct Blueprint {
num_floors: usize,
has_fireplace: bool,
wall_material: Material,
}
impl From<BlueprintOpts> for Blueprint {
fn from(opts: BlueprintOpts) -> Blueprint {
let mut r = Blueprint::default();
opts.into_iter().for_each(|fun| fun(&mut r));
r
}
}
impl Default for Blueprint {
fn default() -> Blueprint {
let (num_floors, has_fireplace, wall_material) = (2, false, Material::Brick);
Blueprint {
num_floors,
has_fireplace,
wall_material,
}
}
}
pub type BlueprintOpt = Box<dyn FnOnce(&mut Blueprint)>;
pub type BlueprintOpts = Vec<BlueprintOpt>;
pub fn with_floors(num_floors: usize) -> BlueprintOpt {
Box::new(move |h| h.num_floors = num_floors)
}
pub fn with_fireplace(has_fireplace: bool) -> BlueprintOpt {
Box::new(move |h| h.has_fireplace = has_fireplace)
}
pub fn with_wall_material(wall_material: Material) -> BlueprintOpt {
Box::new(move |h| h.wall_material = wall_material)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_uses_default() {
let blueprint = Blueprint::from(Vec::new());
assert_eq!(
Blueprint {
num_floors: 2,
has_fireplace: false,
wall_material: Material::Brick,
},
blueprint
);
}
#[test]
fn it_can_set_up_a_house() {
let opts = vec![
with_floors(3),
with_fireplace(true),
with_wall_material(Material::Concrete),
];
let blueprint = Blueprint::from(opts);
assert_eq!(
Blueprint {
num_floors: 3,
has_fireplace: true,
wall_material: Material::Concrete,
},
blueprint
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment