diff options
Diffstat (limited to 'src/structure/building.rs')
-rw-r--r-- | src/structure/building.rs | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/structure/building.rs b/src/structure/building.rs new file mode 100644 index 0000000..b6c6346 --- /dev/null +++ b/src/structure/building.rs @@ -0,0 +1,119 @@ +use std::collections::HashMap; + +use crate::{physics::Point, Render}; + +#[derive(Debug, PartialEq, Eq)] +pub struct Building { + pub position: Point, + pub width: u16, + pub height: u16, + render_map: HashMap<Point, char>, +} + +impl Building { + pub fn builder() -> BuildingBuilder { + BuildingBuilder::default() + } +} + +#[derive(Debug, Default)] +pub struct BuildingBuilder { + position: Option<Point>, + width: Option<u16>, + height: Option<u16>, +} + +impl BuildingBuilder { + pub fn new() -> Self { + Self::default() + } + + pub fn position<P: Into<Point>>(mut self, position: P) -> BuildingBuilder { + self.position = Some(position.into()); + self + } + + pub fn width(mut self, width: u16) -> BuildingBuilder { + self.width = Some(width); + self + } + + pub fn height(mut self, height: u16) -> BuildingBuilder { + self.height = Some(height); + self + } + + pub fn build(self) -> Building { + let position = self.position.unwrap_or_default(); + let width = self.width.unwrap_or_default(); + let height = self.height.unwrap_or_default(); + let mut render_map = HashMap::new(); + + render_map.insert(position, '┌'); + render_map.insert((position.x, height).into(), '└'); + render_map.insert((width, position.y).into(), '┐'); + render_map.insert((width, height).into(), '┘'); + + for x in position.x + 1..width { + render_map.insert((x, position.y).into(), '─'); + render_map.insert((x, height).into(), '─'); + } + + for y in position.y + 1..height { + render_map.insert((position.x, y).into(), '│'); + render_map.insert((width, y).into(), '│'); + } + + Building { + position, + width, + height, + render_map, + } + } +} + +impl Render for Building { + fn render_map(&self) -> &std::collections::HashMap<crate::physics::Point, char> { + &self.render_map + } +} +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use super::*; + use crate::physics::Point; + + #[test] + fn building_builder() { + let position = Point { x: 1, y: 1 }; + let width = 3u16; + let height = 3u16; + let render_map = HashMap::from([ + (position, '┌'), + ((position.x, height).into(), '└'), + ((width, position.y).into(), '┐'), + ((width, height).into(), '┘'), + ((position.x + 1, position.y).into(), '─'), + ((position.x + 1, height).into(), '─'), + ((position.x, position.y + 1).into(), '│'), + ((width, position.y + 1).into(), '│'), + ]); + + let building = Building { + position, + width, + height, + render_map, + }; + + let building_from_builder = BuildingBuilder::new() + .width(width) + .height(height) + .position(position) + .build(); + + assert_eq!(building, building_from_builder); + } +} |