use std::cmp::{Eq, PartialEq};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::sync::LazyLock;
use ustr::Ustr;
use crate::ARCHIPELAGO_NAME;
#[derive(Debug, Clone, Copy)]
pub struct Location {
id: i64,
name: Ustr,
game: Ustr,
}
static CHEAT_CONSOLE: LazyLock<Location> = LazyLock::new(|| Location {
id: -1,
name: "Cheat Console".to_string().into(),
game: *ARCHIPELAGO_NAME,
});
static SERVER: LazyLock<Location> = LazyLock::new(|| Location {
id: -2,
name: "Server".to_string().into(),
game: *ARCHIPELAGO_NAME,
});
impl Location {
pub(crate) fn new(id: i64, name: Ustr, game: Ustr) -> Location {
Location { id, name, game }
}
pub fn cheat_console() -> Location {
*CHEAT_CONSOLE
}
pub fn server() -> Location {
*SERVER
}
pub fn well_known(id: i64) -> Option<Location> {
match id {
-1 => Some(Self::cheat_console()),
-2 => Some(Self::server()),
_ => None,
}
}
pub fn id(&self) -> i64 {
self.id
}
pub fn name(&self) -> Ustr {
self.name
}
pub fn game(&self) -> Ustr {
self.game
}
}
impl fmt::Display for Location {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.fmt(f)
}
}
impl PartialEq for Location {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Location {}
impl Hash for Location {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
pub trait AsLocationId {
fn as_location_id(&self) -> i64;
fn same_location(&self, other: impl AsLocationId) -> bool {
self.as_location_id() == other.as_location_id()
}
}
impl AsLocationId for Location {
fn as_location_id(&self) -> i64 {
self.id
}
}
impl AsLocationId for i64 {
fn as_location_id(&self) -> i64 {
*self
}
}