use std::collections::BTreeMap;
use std::sync::{Arc, Mutex};
use crate::plugin::runtime::PluginObservation;
#[derive(Clone, Default)]
pub(crate) struct SessionFileViews {
inner: Arc<Mutex<SessionFileViewsState>>,
}
#[derive(Default)]
struct SessionFileViewsState {
plugin_files: BTreeMap<SessionFileViewKey, SessionPluginFileView>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct SessionFileViewKey {
pub(crate) branch_id: String,
pub(crate) file_id: String,
}
impl SessionFileViewKey {
pub(crate) fn new(branch_id: impl Into<String>, file_id: impl Into<String>) -> Self {
Self {
branch_id: branch_id.into(),
file_id: file_id.into(),
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct SessionPluginFileView {
pub(crate) path: String,
pub(crate) plugin_key: String,
pub(crate) plugin_generation: String,
pub(crate) owner_change_id: String,
pub(crate) observation: Option<PluginObservation>,
}
#[derive(Debug, Clone)]
pub(crate) enum SessionFileViewMutation {
Set {
key: SessionFileViewKey,
view: SessionPluginFileView,
},
Remove {
key: SessionFileViewKey,
},
}
impl SessionFileViews {
pub(crate) fn has_plugin_file_at_path(&self, branch_id: &str, path: &str) -> bool {
self.lock()
.plugin_files
.iter()
.any(|(key, view)| key.branch_id == branch_id && view.path == path)
}
pub(crate) fn plugin_file_view(
&self,
key: &SessionFileViewKey,
plugin_key: &str,
plugin_generation: &str,
owner_change_id: &str,
) -> Option<SessionPluginFileView> {
self.lock()
.plugin_files
.get(key)
.filter(|view| {
view.plugin_key == plugin_key
&& view.plugin_generation == plugin_generation
&& view.owner_change_id == owner_change_id
})
.cloned()
}
pub(crate) fn remember_plugin_file_view(
&self,
key: SessionFileViewKey,
view: SessionPluginFileView,
) {
self.lock().plugin_files.insert(key, view);
}
pub(crate) fn apply_mutations(
&self,
mutations: impl IntoIterator<Item = SessionFileViewMutation>,
) {
let mut state = self.lock();
for mutation in mutations {
match mutation {
SessionFileViewMutation::Set { key, view } => {
state.plugin_files.insert(key, view);
}
SessionFileViewMutation::Remove { key } => {
state.plugin_files.remove(&key);
}
}
}
}
pub(crate) fn clear(&self) {
self.lock().plugin_files.clear();
}
pub(crate) fn plugin_file_mutations(&self) -> Vec<SessionFileViewMutation> {
self.lock()
.plugin_files
.iter()
.map(|(key, view)| SessionFileViewMutation::Set {
key: key.clone(),
view: view.clone(),
})
.collect()
}
fn lock(&self) -> std::sync::MutexGuard<'_, SessionFileViewsState> {
self.inner
.lock()
.expect("session file view mutex should not poison")
}
}