use crate::db::types::state::Doc;
use candid::Principal;
use junobuild_collections::assert::stores::assert_permission;
use junobuild_collections::types::rules::Permission;
use junobuild_shared::data::list::{filter_timestamps, matcher_regex};
use junobuild_shared::types::core::Key;
use junobuild_shared::types::list::ListParams;
use junobuild_shared::types::state::{AccessKeys, UserId};
use regex::Regex;
pub fn filter_values<'a>(
caller: Principal,
controllers: &'a AccessKeys,
rule: &'a Permission,
col: &'a [(&'a Key, &'a Doc)],
ListParams {
matcher,
order: _,
paginate: _,
owner,
}: &'a ListParams,
) -> Result<Vec<(&'a Key, &'a Doc)>, String> {
let (regex_key, regex_description) = matcher_regex(matcher)?;
let result = col
.iter()
.filter_map(|(key, doc)| {
if filter_key_matcher(®ex_key, key)
&& filter_description_matcher(®ex_description, &doc.description)
&& filter_owner(owner, &doc.owner)
&& filter_timestamps(matcher, *doc)
&& assert_permission(rule, doc.owner, caller, controllers)
{
Some((*key, *doc))
} else {
None
}
})
.collect();
Ok(result)
}
fn filter_key_matcher(regex: &Option<Regex>, key: &Key) -> bool {
match regex {
None => true,
Some(re) => re.is_match(key),
}
}
fn filter_description_matcher(regex: &Option<Regex>, description: &Option<String>) -> bool {
match regex {
None => true,
Some(re) => match description {
None => false,
Some(description) => re.is_match(description),
},
}
}
fn filter_owner(owner: &Option<UserId>, doc_owner: &UserId) -> bool {
match owner {
None => true,
Some(filter_owner) => filter_owner == doc_owner,
}
}