flams_system/backend/archives/
manager.rs1use std::{ops::Deref, path::Path};
2
3use flams_ontology::{
4 content::modules::OpenModule, languages::Language, narration::documents::UncheckedDocument, uris::{ArchiveId, ArchiveURITrait, NameStep, PathURIRef, PathURITrait}, Unchecked
5};
6use flams_utils::change_listener::ChangeSender;
7use oxigraph::model::Quad;
8
9use crate::backend::BackendChange;
10
11use super::{Archive, ArchiveTree};
12
13#[derive(Debug)]
14pub struct ArchiveManager {
15 tree: parking_lot::RwLock<ArchiveTree>,
16 change_sender: ChangeSender<BackendChange>,
17}
18
19impl Default for ArchiveManager {
20 fn default() -> Self {
21 Self {
22 tree: parking_lot::RwLock::new(ArchiveTree::default()),
23 change_sender: ChangeSender::new(256),
24 }
25 }
26}
27impl ArchiveManager {
28 #[inline]
29 #[must_use]
30 pub fn all_archives(&self) -> impl Deref<Target = [Archive]> + '_ {
31 parking_lot::RwLockReadGuard::map(self.tree.read(), |s| s.archives.as_slice())
32 }
33
34 pub fn reinit<'a,R>(&self,f:impl FnOnce(&mut ArchiveTree) -> R,paths:impl IntoIterator<Item = &'a Path,IntoIter : DoubleEndedIterator>) -> R {
35 let mut tree = self.tree.write();
36 let r = f(&mut tree);
37 tree.archives.clear();
38 tree.groups.clear();
39 for p in paths.into_iter().rev() {
40 tree.load(p,&self.change_sender,());
41 }
42 r
43 }
44
45 #[inline]
46 pub fn with_tree<R>(&self,f:impl FnOnce(&ArchiveTree) -> R) -> R {
47 f(&self.tree.read())
48 }
49
50 #[inline]
51 pub fn with_archive<R>(&self, id: &ArchiveId, f: impl FnOnce(Option<&Archive>) -> R) -> R {
52 let tree = self.tree.read();
53 f(tree.get(id))
54 }
55
56 #[inline]
57 pub fn load(&self, path: &Path) {
58 self.do_load(path, ());
59 }
60
61 #[inline]
62 pub fn load_with_quads(&self, path: &Path, add_quad: impl FnMut(Quad) + Send) {
63 self.do_load(path, add_quad);
64 }
65 fn do_load<F: MaybeQuads>(&self, path: &Path, add_quad: F) {
66 let mut tree = self.tree.write();
67 tree.load(path, &self.change_sender, add_quad);
68 }
69
70 pub(crate) fn load_document(
71 &self,
72 path_uri: PathURIRef,
73 language: Language,
74 name: &NameStep,
75 ) -> Option<UncheckedDocument> {
76 let archive = path_uri.archive_id();
77 let path = path_uri.path();
78 self.with_archive(archive, |a| {
79 a.and_then(|a| a.load_document(path, name, language))
80 })
81 }
82 pub(crate) fn load_module(
83 &self,
84 path_uri: PathURIRef,
85 name: &NameStep,
86 ) -> Option<OpenModule<Unchecked>> {
87 let archive = path_uri.archive_id();
88 let path = path_uri.path();
89 self.with_archive(archive, |a| {
90 a.and_then(|a| a.load_module(path, name))
91 })
92 }
93}
94
95pub(super) trait MaybeQuads: Send {}
96impl MaybeQuads for () {}
97impl<F> MaybeQuads for F where F: FnMut(Quad) + Send {}
98
99