use crate::{global::Float, util::Iterable};
use nar_dev_utils::unwrap_or_return;
use serde::{Deserialize, Serialize};
pub trait RankTable<T>: Iterable<T> {
fn size(&self) -> usize;
fn is_empty(&self) -> bool {
self.size() == 0
}
fn capacity(&self) -> usize;
fn rank(&self, item: &T) -> Float;
fn __get(&self, index: usize) -> Option<&T>;
fn __insert(&mut self, index: usize, item: T);
fn __push(&mut self, item: T);
fn __pop(&mut self) -> Option<T>;
fn rank_index_to_add(&self, item: &T) -> Option<usize> {
let rank_new = self.rank(item);
for (i_to_add, existed) in self.iter().enumerate() {
let rank_existed = self.rank(existed);
if rank_new >= rank_existed {
return match self.is_compatible_to_add(item, existed) {
true => Some(i_to_add),
false => None,
};
}
}
Some(self.size())
}
fn is_compatible_to_add(&self, new_item: &T, existed_item: &T) -> bool;
fn add(&mut self, new_item: T) -> Option<T> {
let i_to_add = unwrap_or_return! {
?self.rank_index_to_add(&new_item)
=> Some(new_item)
};
let table_size = self.size();
match (i_to_add == table_size, table_size == self.capacity()) {
(true, true) => return Some(new_item),
(true, false) => self.__push(new_item),
(false, _) => self.__insert(i_to_add, new_item),
}
let new_size = self.size();
match new_size > self.capacity() {
true => {
debug_assert!(
new_size - self.capacity() == 1,
"【2024-06-08 10:07:31】断言:一次只会添加一个,并且容量不会突然变化"
);
self.__pop()
}
false => None,
}
}
}
pub type RankF<T> = for<'a> fn(&'a T) -> Float;
pub type IsCompatibleToAddF<T> = for<'a> fn(&'a T, &'a T) -> bool;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ArrayRankTable<T> {
inner: Vec<T>,
capacity: usize,
#[serde(skip)]
#[serde(default = "ArrayRankTable::<T>::default_rank_f")]
rank_f: RankF<T>,
#[serde(skip)]
#[serde(default = "ArrayRankTable::<T>::default_is_compatible_to_add_f")]
is_compatible_to_add_f: IsCompatibleToAddF<T>,
}
impl<T> ArrayRankTable<T> {
pub fn new(
capacity: usize,
rank_f: RankF<T>,
is_compatible_to_add_f: IsCompatibleToAddF<T>,
) -> Self {
Self {
inner: vec![],
capacity,
rank_f,
is_compatible_to_add_f,
}
}
}
impl<T> Iterable<T> for ArrayRankTable<T> {
type Iter<'a> = core::slice::Iter<'a,T>
where
Self: 'a,
T: 'a;
fn iter(&self) -> Self::Iter<'_> {
self.inner.iter()
}
type IterMut<'a>= core::slice::IterMut<'a,T>
where
Self: 'a,
T: 'a;
fn iter_mut(&mut self) -> Self::IterMut<'_> {
self.inner.iter_mut()
}
}
impl<T> RankTable<T> for ArrayRankTable<T> {
fn rank(&self, item: &T) -> Float {
(self.rank_f)(item)
}
fn is_compatible_to_add(&self, new_item: &T, existed_item: &T) -> bool {
(self.is_compatible_to_add_f)(new_item, existed_item)
}
fn size(&self) -> usize {
self.inner.len()
}
fn capacity(&self) -> usize {
self.capacity
}
fn __get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
fn __insert(&mut self, index: usize, item: T) {
self.inner.insert(index, item)
}
fn __push(&mut self, item: T) {
self.inner.push(item)
}
fn __pop(&mut self) -> Option<T> {
self.inner.pop()
}
}
impl<T> ArrayRankTable<T> {
pub fn override_fn(&mut self, rank_f: RankF<T>, is_compatible_to_add_f: IsCompatibleToAddF<T>) {
self.rank_f = rank_f;
self.is_compatible_to_add_f = is_compatible_to_add_f;
}
pub fn default_rank_f() -> RankF<T> {
fn rank_f<T>(_: &T) -> Float {
panic!("未完全反序列化的`rank_f`函数指针")
}
rank_f
}
pub fn default_is_compatible_to_add_f() -> IsCompatibleToAddF<T> {
fn is_compatible_to_add_f<T>(_: &T, _: &T) -> bool {
panic!("未完全反序列化的`is_compatible_to_add_f`函数指针")
}
is_compatible_to_add_f
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{ok, util::AResult};
#[test]
fn ser() -> AResult {
let table = ArrayRankTable::new(
10,
{
fn rank_f(item: &i32) -> Float {
*item as Float
}
rank_f
},
{
fn is_compatible_to_add_f(new_item: &i32, existed_item: &i32) -> bool {
*new_item > *existed_item
}
is_compatible_to_add_f
},
);
let s = serde_json::to_string(&table)?;
println!("{table:?} => {s}");
ok!()
}
}