flams_system/backend/archives/
manager.rs

1use 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/*
100#[cfg(test)]
101mod tests {
102
103    use flams_ontology::source_format;
104    use flams_utils::time::measure;
105
106    use super::*;
107
108    source_format!(stex ["tex","ltx"] [] @
109        "Semantically annotated LaTeX"
110    );
111
112    #[test]
113    fn mathhub() {
114        use std::fmt::Write;
115        let subscriber = tracing_subscriber::FmtSubscriber::builder()
116        //.with_max_level(tracing::Level::DEBUG)
117        .finish();
118        tracing::subscriber::set_global_default(subscriber).unwrap();
119        let manager = ArchiveManager::default();
120        let (_,t) = measure(|| manager.load(Path::new("/home/jazzpirate/work/MathHub")));
121
122        tracing::info!("Loaded archives in {t}");
123
124        let mut all = String::new();
125        for a in &*manager.all_archives() {
126        write!(all,"{}, ",a.id()).unwrap();
127        }
128        tracing::info!("{all}");
129
130        assert_eq!(165,manager.all_archives().len());
131    }
132}
133*/