use crate::{FirestoreDb, FirestoreListenerTarget};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct FirestoreCacheConfiguration {
pub collections: HashMap<String, FirestoreCacheCollectionConfiguration>,
pub incomplete_collection_policy: FirestoreCacheIncompleteCollectionPolicy,
}
impl FirestoreCacheConfiguration {
#[inline]
pub fn new() -> Self {
Self {
collections: HashMap::new(),
incomplete_collection_policy: FirestoreCacheIncompleteCollectionPolicy::default(),
}
}
#[inline]
pub fn add_collection_config(
self,
db: &FirestoreDb,
config: FirestoreCacheCollectionConfiguration,
) -> Self {
self.add_collection_config_at(db.get_documents_path(), config)
}
#[inline]
pub fn with_incomplete_collection_policy(
self,
incomplete_collection_policy: FirestoreCacheIncompleteCollectionPolicy,
) -> Self {
Self {
incomplete_collection_policy,
..self
}
}
#[inline]
pub(crate) fn add_collection_config_at(
mut self,
documents_path: &str,
config: FirestoreCacheCollectionConfiguration,
) -> Self {
let collection_path = config.resolve_collection_path(documents_path);
self.collections.insert(collection_path, config);
self
}
#[inline]
pub fn is_collection_listable(&self, collection_path: &str) -> bool {
match self.collections.get(collection_path) {
Some(config) => match self.incomplete_collection_policy {
FirestoreCacheIncompleteCollectionPolicy::SkipCache => {
config.collection_load_mode.is_preloading()
}
FirestoreCacheIncompleteCollectionPolicy::PartialResults => true,
},
None => false,
}
}
}
impl Default for FirestoreCacheConfiguration {
#[inline]
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
pub enum FirestoreCacheIncompleteCollectionPolicy {
#[default]
SkipCache,
PartialResults,
}
#[derive(Debug, Clone)]
pub struct FirestoreCacheCollectionConfiguration {
pub collection_name: String,
pub parent: Option<String>,
pub listener_target: FirestoreListenerTarget,
pub collection_load_mode: FirestoreCacheCollectionLoadMode,
#[doc(hidden)]
pub indices: Vec<FirestoreCacheIndexConfiguration>,
}
impl FirestoreCacheCollectionConfiguration {
#[inline]
pub fn new<S>(
collection_name: S,
listener_target: FirestoreListenerTarget,
collection_load_mode: FirestoreCacheCollectionLoadMode,
) -> Self
where
S: AsRef<str>,
{
Self {
collection_name: collection_name.as_ref().to_string(),
parent: None,
listener_target,
collection_load_mode,
indices: Vec::new(),
}
}
#[inline]
pub fn with_parent<S>(self, parent: S) -> Self
where
S: AsRef<str>,
{
Self {
parent: Some(parent.as_ref().to_string()),
..self
}
}
#[doc(hidden)]
#[deprecated(
since = "0.52.0",
note = "Cache indices are not implemented and have no effect. This method is scheduled for removal."
)]
#[inline]
pub fn with_index(self, index: FirestoreCacheIndexConfiguration) -> Self {
let mut indices = self.indices;
indices.push(index);
Self { indices, ..self }
}
#[inline]
pub(crate) fn resolve_collection_path(&self, documents_path: &str) -> String {
match self.parent {
Some(ref parent) => format!("{}/{}", parent, self.collection_name),
None => format!("{}/{}", documents_path, self.collection_name),
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum FirestoreCacheCollectionLoadMode {
PreloadAllDocs,
PreloadAllIfEmpty,
PreloadNone,
}
impl FirestoreCacheCollectionLoadMode {
#[inline]
pub fn is_preloading(&self) -> bool {
matches!(self, Self::PreloadAllDocs | Self::PreloadAllIfEmpty)
}
}
#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct FirestoreCacheIndexConfiguration {
pub fields: Vec<String>,
pub unique: bool,
}
impl FirestoreCacheIndexConfiguration {
#[inline]
pub fn new<I>(fields: I) -> Self
where
I: IntoIterator,
I::Item: AsRef<str>,
{
Self {
fields: fields.into_iter().map(|s| s.as_ref().to_string()).collect(),
unique: false,
}
}
#[inline]
pub fn unique(self, value: bool) -> Self {
Self {
unique: value,
..self
}
}
}