use super::types::*;
use issun_macros::Resource as DeriveResource;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize, DeriveResource)]
pub struct Territories {
territories: HashMap<TerritoryId, Territory>,
}
impl Territories {
pub fn new() -> Self {
Self {
territories: HashMap::new(),
}
}
pub fn add(&mut self, territory: Territory) {
self.territories.insert(territory.id.clone(), territory);
}
pub fn get(&self, id: &TerritoryId) -> Option<&Territory> {
self.territories.get(id)
}
pub fn contains(&self, id: &TerritoryId) -> bool {
self.territories.contains_key(id)
}
pub fn len(&self) -> usize {
self.territories.len()
}
pub fn is_empty(&self) -> bool {
self.territories.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &Territory> {
self.territories.values()
}
pub fn query<F>(&self, predicate: F) -> Vec<&Territory>
where
F: Fn(&Territory) -> bool,
{
self.territories.values().filter(|t| predicate(t)).collect()
}
}
impl Default for Territories {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_territories_new() {
let territories = Territories::new();
assert_eq!(territories.len(), 0);
assert!(territories.is_empty());
}
#[test]
fn test_add_and_get() {
let mut territories = Territories::new();
let territory = Territory::new("nova", "Nova Harbor");
territories.add(territory);
assert_eq!(territories.len(), 1);
assert!(!territories.is_empty());
let retrieved = territories.get(&TerritoryId::new("nova"));
assert!(retrieved.is_some());
assert_eq!(retrieved.unwrap().name, "Nova Harbor");
}
#[test]
fn test_contains() {
let mut territories = Territories::new();
territories.add(Territory::new("nova", "Nova Harbor"));
assert!(territories.contains(&TerritoryId::new("nova")));
assert!(!territories.contains(&TerritoryId::new("rust")));
}
#[test]
fn test_iter() {
let mut territories = Territories::new();
territories.add(Territory::new("nova", "Nova Harbor"));
territories.add(Territory::new("rust", "Rust City"));
let count = territories.iter().count();
assert_eq!(count, 2);
let names: Vec<_> = territories.iter().map(|t| t.name.as_str()).collect();
assert!(names.contains(&"Nova Harbor"));
assert!(names.contains(&"Rust City"));
}
#[test]
fn test_query() {
let mut territories = Territories::new();
territories.add(Territory::new("nova", "Nova Harbor"));
territories.add(Territory::new("rust", "Rust City"));
let nova_only = territories.query(|t| t.name == "Nova Harbor");
assert_eq!(nova_only.len(), 1);
assert_eq!(nova_only[0].id.as_str(), "nova");
}
}