1use crate::types::{Membership, ScopeRef};
4use std::collections::HashMap;
5use std::sync::{Arc, Mutex};
6
7type CacheKey = (String, i64, i64);
8
9#[derive(Clone, Default)]
10pub struct MembershipCache {
11 inner: Arc<Mutex<HashMap<CacheKey, Membership>>>,
12}
13
14impl MembershipCache {
15 pub fn new() -> Self {
16 Self::default()
17 }
18
19 fn key(scope: &ScopeRef, user_id: i64) -> CacheKey {
20 (scope.kind.clone(), scope.id, user_id)
21 }
22
23 pub fn get(&self, scope: &ScopeRef, user_id: i64) -> Option<Membership> {
24 self.inner
25 .lock()
26 .unwrap_or_else(|e| e.into_inner())
27 .get(&Self::key(scope, user_id))
28 .cloned()
29 }
30
31 pub fn put(&self, membership: Membership) {
32 let key = (
33 membership.scope_kind.clone(),
34 membership.scope_id,
35 membership.user_id,
36 );
37 self.inner
38 .lock()
39 .unwrap_or_else(|e| e.into_inner())
40 .insert(key, membership);
41 }
42
43 pub fn invalidate(&self, scope: &ScopeRef, user_id: i64) {
44 self.inner
45 .lock()
46 .unwrap_or_else(|e| e.into_inner())
47 .remove(&Self::key(scope, user_id));
48 }
49
50 pub fn invalidate_scope(&self, scope: &ScopeRef) {
51 let mut guard = self.inner.lock().unwrap_or_else(|e| e.into_inner());
52 guard.retain(|(kind, id, _), _| !(kind == &scope.kind && *id == scope.id));
53 }
54
55 pub fn clear(&self) {
56 self.inner
57 .lock()
58 .unwrap_or_else(|e| e.into_inner())
59 .clear();
60 }
61}
62
63#[derive(Clone, Copy, Default)]
65pub struct MutateOpts<'a> {
66 pub actor_id: Option<i64>,
67 pub cache: Option<&'a MembershipCache>,
68}
69
70impl<'a> MutateOpts<'a> {
71 pub fn new() -> Self {
72 Self::default()
73 }
74
75 pub fn actor(mut self, actor_id: i64) -> Self {
76 self.actor_id = Some(actor_id);
77 self
78 }
79
80 pub fn cache(mut self, cache: &'a MembershipCache) -> Self {
81 self.cache = Some(cache);
82 self
83 }
84}