use std::{borrow::Borrow, hash::Hash, ops::Deref, sync::Arc};
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use crate::{
cache::{CacheError, Mod},
decks::DeckConfig,
error::{AnkiError, AnkiResult},
AnkiModules, Number,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct DeckCache<K>
where
K: Hash + Eq,
{
#[serde(skip)]
modules: Mod,
cache: IndexMap<K, Option<DeckConfig>>,
}
impl<K> DeckCache<K>
where
K: Hash + Eq,
{
pub fn new(modules: Arc<AnkiModules>) -> Self {
Self {
modules: modules.into(),
cache: IndexMap::new(),
}
}
}
impl DeckCache<String> {
pub fn hydrate_names(&mut self) -> AnkiResult<&mut Self> {
let Some(modules) = &self.modules else {
return Err(AnkiError::Cache(CacheError::Dehydrated));
};
let latest: IndexMap<String, Number> = modules.decks.get_all_deck_names_and_ids()?;
for (name, _) in latest {
if !self.cache.contains_key(&name) {
self.cache.insert(name, None);
} else {
}
}
Ok(self)
}
}
impl<K> DeckCache<K>
where
K: Hash + Eq,
{
pub fn find_many_from_key_owned<'a, Q>(
&'a self,
keys: &'a [&Q],
) -> impl Iterator<Item = (K, Option<DeckConfig>)> + 'a
where
K: Borrow<Q> + Clone,
Q: Hash + Eq + ?Sized,
{
keys.iter()
.filter_map(move |key| self.get_key_value(*key))
.map(|(k, v)| (k.clone(), v.clone()))
}
pub fn get_cache(&self) -> &IndexMap<K, Option<DeckConfig>> {
&self.cache
}
pub fn take_cache(self) -> IndexMap<K, Option<DeckConfig>> {
self.cache
}
}
impl<K> Deref for DeckCache<K>
where
K: Hash + Eq,
{
type Target = IndexMap<K, Option<DeckConfig>>;
fn deref(&self) -> &Self::Target {
&self.cache
}
}
impl<T: Eq + Hash> From<DeckCache<T>> for IndexMap<T, Option<DeckConfig>> {
fn from(val: DeckCache<T>) -> Self {
val.cache
}
}