Created
February 4, 2024 00:31
-
-
Save kiyov09/dc9520a383e3cf8c16ef4f23551e7c2e to your computer and use it in GitHub Desktop.
Rust house builder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(unused)] | |
use std::marker::PhantomData; | |
/// Our beloved house | |
#[derive(Debug)] | |
struct House { | |
floors: u32, | |
rooms: u32, | |
has_garage: bool, | |
} | |
/// The states representing the status of the construction | |
struct Blueprint; | |
struct HasFloors; | |
struct HasRooms; | |
struct HasGarage; | |
struct HasFloorsAndRooms; | |
struct HasGarageAndRooms; | |
struct HasGarageAndFloors; | |
struct Ready; | |
/// A trait any struct that want to be consider as state needs to implement | |
trait BuilderState {} | |
impl BuilderState for Blueprint {} | |
impl BuilderState for HasGarage {} | |
impl BuilderState for HasGarageAndRooms {} | |
impl BuilderState for HasGarageAndFloors {} | |
impl BuilderState for HasFloors {} | |
impl BuilderState for HasFloorsAndRooms {} | |
impl BuilderState for HasRooms {} | |
impl BuilderState for Ready {} | |
struct HouseBuilder<T: BuilderState> { | |
_floors: u32, | |
_rooms: u32, | |
_has_garage: bool, | |
_marker: PhantomData<T>, | |
} | |
impl HouseBuilder<Blueprint> { | |
fn new() -> Self { | |
Self { | |
_floors: 0, | |
_rooms: 0, | |
_has_garage: false, | |
_marker: PhantomData, | |
} | |
} | |
fn floors(self, floors: u32) -> HouseBuilder<HasFloors> { | |
HouseBuilder { | |
_floors: floors, | |
_rooms: self._rooms, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
fn rooms(self, rooms: u32) -> HouseBuilder<HasRooms> { | |
HouseBuilder { | |
_rooms: rooms, | |
_floors: self._floors, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
fn with_garage(self) -> HouseBuilder<HasGarage> { | |
HouseBuilder { | |
_has_garage: true, | |
_rooms: self._rooms, | |
_floors: self._floors, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasGarage> { | |
fn floors(self, floors: u32) -> HouseBuilder<HasGarageAndFloors> { | |
HouseBuilder { | |
_floors: floors, | |
_rooms: self._rooms, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
fn rooms(self, rooms: u32) -> HouseBuilder<HasGarageAndRooms> { | |
HouseBuilder { | |
_rooms: rooms, | |
_floors: self._floors, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasRooms> { | |
fn floors(self, floors: u32) -> HouseBuilder<HasFloorsAndRooms> { | |
HouseBuilder { | |
_floors: floors, | |
_rooms: self._rooms, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
fn with_garage(self) -> HouseBuilder<HasGarageAndRooms> { | |
HouseBuilder { | |
_has_garage: true, | |
_rooms: self._rooms, | |
_floors: self._floors, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasFloors> { | |
fn rooms(self, rooms: u32) -> HouseBuilder<HasFloorsAndRooms> { | |
HouseBuilder { | |
_rooms: rooms, | |
_floors: self._floors, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
fn with_garage(self) -> HouseBuilder<HasGarageAndFloors> { | |
HouseBuilder { | |
_has_garage: true, | |
_rooms: self._rooms, | |
_floors: self._floors, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasGarageAndFloors> { | |
fn rooms(self, rooms: u32) -> HouseBuilder<Ready> { | |
HouseBuilder { | |
_rooms: rooms, | |
_floors: self._floors, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasGarageAndRooms> { | |
fn floors(self, floors: u32) -> HouseBuilder<Ready> { | |
HouseBuilder { | |
_floors: floors, | |
_rooms: self._rooms, | |
_has_garage: self._has_garage, | |
_marker: PhantomData, | |
} | |
} | |
} | |
impl HouseBuilder<HasFloorsAndRooms> { | |
fn with_garage(self) -> HouseBuilder<Ready> { | |
HouseBuilder { | |
_has_garage: true, | |
_rooms: self._rooms, | |
_floors: self._floors, | |
_marker: PhantomData, | |
} | |
} | |
fn build(self) -> House { | |
House { | |
floors: self._floors, | |
rooms: self._rooms, | |
has_garage: self._has_garage, | |
} | |
} | |
} | |
impl HouseBuilder<Ready> { | |
fn build(self) -> House { | |
House { | |
floors: self._floors, | |
rooms: self._rooms, | |
has_garage: self._has_garage, | |
} | |
} | |
} | |
fn main() { | |
let house = HouseBuilder::new().with_garage().floors(2).rooms(2).build(); | |
let house = HouseBuilder::new().with_garage().rooms(2).floors(2).build(); | |
let house = HouseBuilder::new().rooms(2).floors(2).build(); | |
let house = HouseBuilder::new().rooms(2).floors(2).with_garage().build(); | |
let house = HouseBuilder::new().rooms(2).with_garage().floors(2).build(); | |
let house = HouseBuilder::new().floors(2).rooms(2).build(); | |
let house = HouseBuilder::new().floors(2).rooms(2).with_garage().build(); | |
let house = HouseBuilder::new().floors(2).with_garage().rooms(2).build(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment