94 lines
2.0 KiB
94 lines
2.0 KiB
use std::collections::HashMap;
|
|
use std::convert::TryFrom;
|
|
use std::error::Error;
|
|
|
|
use rusqlite::Row;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
|
|
use crate::id::Id;
|
|
use crate::try_log;
|
|
use crate::world::{Area, AreaType, Direction, Exit, DIRECTION_LIST};
|
|
|
|
/// A specific location in the world.
|
|
#[derive(Debug, Deserialize, Serialize)]
|
|
pub struct Room {
|
|
/// Unique identifier
|
|
pub id: Id,
|
|
|
|
/// Parent zone that the room is in
|
|
pub zone: Id,
|
|
|
|
/// Name of the room
|
|
pub name: String,
|
|
|
|
/// Description, each line an entry in a `Vec`
|
|
pub description: Vec<String>,
|
|
|
|
/// Whether users in the room should be visible to the parent zone
|
|
pub users_visible: bool,
|
|
|
|
/// Exits from the room
|
|
pub exits: HashMap<Direction, Exit>,
|
|
}
|
|
|
|
impl Room {
|
|
/// Return a list of available exits by the short identifier
|
|
pub fn exit_string(&self) -> String {
|
|
if self.exits.is_empty() {
|
|
return String::new();
|
|
}
|
|
|
|
DIRECTION_LIST
|
|
.iter()
|
|
.filter_map(|(_, direction)| {
|
|
if self.exits.contains_key(direction) {
|
|
Some(direction.short())
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect::<Vec<&str>>()
|
|
.join(" ")
|
|
}
|
|
}
|
|
|
|
impl Area for Room {
|
|
fn id(&self) -> Id {
|
|
self.id
|
|
}
|
|
|
|
fn parent(&self) -> Id {
|
|
self.zone
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
self.name.to_owned()
|
|
}
|
|
|
|
fn visible(&self) -> bool {
|
|
self.users_visible
|
|
}
|
|
|
|
fn area_type(&self) -> AreaType {
|
|
AreaType::Room
|
|
}
|
|
}
|
|
|
|
impl<'a> TryFrom<&Row<'a>> for Room {
|
|
type Error = Box<dyn Error>;
|
|
|
|
fn try_from(row: &Row) -> Result<Self, Self::Error> {
|
|
Ok(Self {
|
|
id: try_log!(row.get("id"), "Unable to get column 'id' from row"),
|
|
zone: try_log!(row.get("zone"), "Unable to get column 'zone' from row"),
|
|
name: try_log!(row.get("name"), "Unable to get column 'name' from row"),
|
|
description: try_log!(row.get::<&str, String>("description"), "Unable to get column 'description' from row")
|
|
.lines()
|
|
.map(|s| String::from(s))
|
|
.collect(),
|
|
users_visible: try_log!(row.get("users_visible"), "Unable to get column 'users_visible' from row"),
|
|
exits: HashMap::new(),
|
|
})
|
|
}
|
|
}
|