use crate::entity::Item;
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, VecDeque},
fmt::Debug,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BagNameTable<E: Item>(HashMap<String, NameValue<E>>);
pub type NameValue<E> = (E, usize);
impl<E: Item> BagNameTable<E> {
pub fn new() -> Self {
Self(HashMap::new())
}
pub(super) fn debug_display(&self) -> String {
format!(
"BagNameTable(len={}) {{\n{}\n}}",
self.0.len(),
self.0
.iter()
.map(|(k, (v, l))| format!("{k:?}: ({:?}, {l:?})", v.to_display()))
.collect::<Vec<_>>()
.join("\n")
)
}
}
impl<E: Item> Default for BagNameTable<E> {
fn default() -> Self {
Self::new()
}
}
impl<E: Item> BagNameTable<E> {
pub fn size(&self) -> usize {
self.0.len()
}
pub fn get(&self, key: &str) -> Option<&NameValue<E>> {
self.0.get(key)
}
pub fn get_mut(&mut self, key: &str) -> Option<&mut NameValue<E>> {
self.0.get_mut(key)
}
pub fn has(&self, key: &str) -> bool {
self.get(key).is_some()
}
pub fn put(&mut self, key: &str, item: E, level: usize) -> Option<NameValue<E>> {
let name_value = (item, level);
self.0.insert(key.to_string(), name_value)
}
pub fn remove(&mut self, key: &str) -> Option<NameValue<E>> {
self.0.remove(key)
}
pub fn remove_item(&mut self, key: &str) -> Option<E> {
self.0.remove(key).map(|(item, _)| item)
}
pub fn is_empty(&self) -> bool {
self.size() == 0
}
pub(super) fn iter(&self) -> impl Iterator<Item = (&String, &NameValue<E>)> {
self.0.iter()
}
pub(super) fn iter_items(&self) -> impl Iterator<Item = &E> {
self.0.values().map(|(item, _)| item)
}
pub(super) fn iter_items_mut(&mut self) -> impl Iterator<Item = &mut E> {
self.0.values_mut().map(|(item, _)| item)
}
}
#[derive(Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct BagItemTable(Box<[BagItemLevel]>);
impl BagItemTable {
pub fn new(levels: usize) -> Self {
let inner = vec![BagItemLevel::new(); levels].into_boxed_slice();
Self(inner)
}
}
impl Debug for BagItemTable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.0.is_empty() {
write!(f, "BagItemTable([])")
} else {
let mut debug_struct = f.debug_struct(std::any::type_name::<Self>());
for (i, level) in self.0.iter().enumerate() {
if !level.is_empty() {
debug_struct.field(&format!("level_{i} ({})", level.size()), &level);
}
}
debug_struct.finish()
}
}
}
impl BagItemTable {
pub fn add_new(&mut self, level: usize) {
self.0[level] = BagItemLevel::new();
}
pub fn get(&self, level: usize) -> &BagItemLevel {
&self.0[level]
}
pub fn get_mut(&mut self, level: usize) -> &mut BagItemLevel {
&mut self.0[level]
}
pub fn count(&self) -> usize {
self.0.iter().map(BagItemLevel::size).sum()
}
pub(super) fn iter(&self) -> impl Iterator<Item = &BagItemLevel> {
self.0.iter()
}
pub fn remove_element(&mut self, key: &str) {
for level in self.0.iter_mut() {
for i in (0..level.size()).rev() {
let item_key = &level.0[i];
if item_key == key {
level.0.remove(i);
}
}
}
}
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct BagItemLevel(VecDeque<String>);
impl BagItemLevel {
pub fn new() -> Self {
Self(VecDeque::new())
}
pub fn size(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn add(&mut self, key: String) {
debug_assert!(
self.0.iter().all(|k| k != &key),
"不允许添加重复值:key={key}, self={self:?}"
);
self.0.push_back(key)
}
pub fn get(&self, index: usize) -> Option<&String> {
self.0.get(index)
}
#[inline(always)]
pub fn get_first(&self) -> Option<&String> {
self.0.front()
}
pub fn remove_first(&mut self) {
self.0.pop_front();
}
pub(super) fn iter(&self) -> impl DoubleEndedIterator<Item = &String> {
self.0.iter()
}
}