use crate::{decoders::timespec_seconds, error};
#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum RoomState {
Nonexistant,
Closed,
Open,
Novice {
#[serde(with = "timespec_seconds")]
end_time: time::Timespec,
},
SecondTierNovice {
#[serde(with = "timespec_seconds")]
room_open_time: time::Timespec,
#[serde(with = "timespec_seconds")]
end_time: time::Timespec,
},
}
impl RoomState {
pub fn from_data(
current_time: time::Timespec,
novice_end: Option<time::Timespec>,
open_time: Option<time::Timespec>,
) -> Result<Self, error::ApiError> {
let state = match novice_end {
Some(n) if n > current_time => match open_time {
Some(o) if o > current_time => RoomState::SecondTierNovice {
room_open_time: o,
end_time: n,
},
_ => RoomState::Novice { end_time: n },
},
Some(_) | None => RoomState::Open,
};
Ok(state)
}
pub fn non_existant() -> Self {
RoomState::Nonexistant
}
pub fn closed() -> Self {
RoomState::Closed
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Hash, Debug)]
pub struct RoomSign {
#[serde(rename = "time")]
pub game_time_set: u32,
#[serde(with = "timespec_seconds")]
#[serde(rename = "datetime")]
pub time_set: time::Timespec,
#[serde(rename = "user")]
pub user_id: String,
pub text: String,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Hash, Debug)]
pub struct HardSign {
#[serde(rename = "time")]
pub game_time_set: u32,
#[serde(with = "timespec_seconds")]
#[serde(rename = "datetime")]
pub start: time::Timespec,
#[serde(with = "timespec_seconds")]
#[serde(rename = "endDatetime")]
pub end: time::Timespec,
pub text: String,
}
#[cfg(test)]
mod tests {
use serde_json;
use time;
use super::{HardSign, RoomSign, RoomState};
#[test]
fn parse_room_state_open_never_novice() {
let state = RoomState::from_data(time::Timespec::new(1, 0), None, None).unwrap();
assert_eq!(state, RoomState::Open);
}
#[test]
fn parse_room_state_open_previously_novice() {
let state = RoomState::from_data(
time::Timespec::new(4, 0),
Some(time::Timespec::new(3, 0)),
Some(time::Timespec::new(2, 0)),
)
.unwrap();
assert_eq!(state, RoomState::Open);
}
#[test]
fn parse_room_state_novice_never_closed() {
let state = RoomState::from_data(
time::Timespec::new(4, 0),
Some(time::Timespec::new(10, 0)),
None,
)
.unwrap();
assert_eq!(
state,
RoomState::Novice {
end_time: time::Timespec::new(10, 0),
}
);
}
#[test]
fn parse_room_state_novice_previously_second_tier() {
let state = RoomState::from_data(
time::Timespec::new(4, 0),
Some(time::Timespec::new(10, 0)),
Some(time::Timespec::new(2, 0)),
)
.unwrap();
assert_eq!(
state,
RoomState::Novice {
end_time: time::Timespec::new(10, 0),
}
);
}
#[test]
fn parse_room_state_second_tier_novice() {
let state = RoomState::from_data(
time::Timespec::new(10, 0),
Some(time::Timespec::new(20, 0)),
Some(time::Timespec::new(15, 0)),
)
.unwrap();
assert_eq!(
state,
RoomState::SecondTierNovice {
room_open_time: time::Timespec::new(15, 0),
end_time: time::Timespec::new(20, 0),
}
);
}
#[test]
fn parse_room_sign() {
let _: RoomSign = serde_json::from_value(json!({
"time": 16656131,
"text": "I have plans for this block",
"datetime": 1484071532985i64,
"user": "57c7df771d90a0c561977377"
}))
.unwrap();
}
#[test]
fn parse_hard_sign() {
let _: HardSign = serde_json::from_value(json!({
"time": 18297994,
"datetime": 1490632558393i64,
"text": "A new Novice Area is being planned somewhere in this sector. \
Please make sure all important rooms are reserved.",
"endDatetime": 1490978122587i64
}))
.unwrap();
}
}