1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

//! The rooms of Simmons Hall
//!
//! Originally written in Python by cosmosd in Sept. 2013
//! Recreated in Rust by zrneely in Apr. 2016

#![deny(missing_docs, trivial_casts,
        trivial_numeric_casts, unstable_features,
        unused_import_braces, unused_qualifications)]

#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

#[macro_use]
extern crate lazy_static;

pub mod data;

use std::fmt;

/// A room number.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct RoomNumber<'a> {
    /// The integral part of the room number. For example, "741" or "232".
    pub integer: u32,
    /// The suffix of the room number. For example, "A" or "B".
    pub suffix: Option<&'a str>,
}
impl<'a> fmt::Display for RoomNumber<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}{}", self.integer, self.suffix.unwrap_or(""))
    }
}

/// One of the GRT Sections in Simmons.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct GrtSection<'a> {
    /// A label for this section.
    pub label: &'a str,
    /// The room numbers which are part of this section.
    pub numbers: Vec<RoomNumber<'a>>,
}
impl<'a> fmt::Display for GrtSection<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.label)
    }
}

/// The capacity of a room.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Capacity {
    /// The room can hold a single occupant.
    Single,
    /// The room can hold two occupants.
    Double,
}

/// Some amount of square feet.
pub type SquareFeet = u64;

/// The view a room has.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum View {
    /// A view of Boston.
    Boston,
    /// A view of Cambridge.
    Cambridge,
}

/// How curvy the walls in a room are.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Curviness {
    /// The room is square.
    Square,
    /// The room has some curvy walls, but not too bad.
    Minor,
    /// The room has significantly curvy walls.
    Major,
    /// The room has REALLY curvy walls.
    Awful,
}

/// Where a bathroom is located.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BathroomLocation {
    /// The bathroom is in the room.
    Interior,
    /// The bathroom is in the hallway.
    Hallway,
    /// The bathroom is in the suite.
    InSuite,
}

/// A bathroom.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Bathroom<'a> {
    /// Even bathrooms have room numbers.
    pub number: RoomNumber<'a>,
    /// Which rooms do this bathroom service?
    pub rooms: Vec<RoomNumber<'a>>,
    /// Where is this bathroom?
    pub location: BathroomLocation,
}
impl<'a> fmt::Display for Bathroom<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "# Rooms: {}, Location: {:?}", self.rooms.len(), self.location)
    }
}

/// A room.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Room<'a> {
    /// The GRT section of this room.
    pub grt_section: GrtSection<'a>,
    /// The capacity of this room.
    pub capacity: Capacity,
    /// The size of this room.
    pub size: SquareFeet,
    /// Which side of Simmons this room looks out onto.
    pub view: View,
    /// How curvy the walls are.
    pub curviness: Curviness,
    /// Which bathroom this room has.
    pub bathroom: Bathroom<'a>,
}
impl<'a> fmt::Display for Room<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt,
               "Capacity: {:?}, Size: {} sq. ft., View: {:?}, Curviness: {:?}, Section: {}, Bathroom: [{}]",
               self.capacity,
               self.size,
               self.view,
               self.curviness,
               self.grt_section,
               self.bathroom)
    }
}

#[cfg(test)]
#[test]
fn test_consistency() {
    let length = data::ROOMS.len();
    println!("{}", length);
}