Skip to main content

flams_math_archives/
document_file.rs

1use std::path::PathBuf;
2
3use crate::utils::{
4    AsyncEngine,
5    errors::ReadError,
6    lazy_file::{BytesField, EagerField, LazyField, LazyFile, StreamField},
7};
8use ftml_ontology::{
9    narrative::{DocumentRange, documents::Document},
10    utils::Css,
11};
12
13#[derive(Debug)]
14pub struct DocumentFile {
15    reader: LazyFile<6>,
16    body: EagerField<DocumentRange, 0>,
17    inner_offset: EagerField<u32, 1>,
18    css: EagerField<Box<[Css]>, 2>,
19    data: BytesField<3>,
20    document: LazyField<Document, 4>,
21    html: StreamField<5>,
22}
23impl DocumentFile {
24    pub(crate) fn get_all(
25        self,
26    ) -> Result<
27        (
28            DocumentRange,
29            u32,
30            Box<[Css]>,
31            Box<[u8]>,
32            Document,
33            Box<str>,
34        ),
35        ReadError,
36    > {
37        Ok((
38            self.body.get().clone(),
39            *self.inner_offset.get(),
40            self.css.get().clone(),
41            self.data.get(&self.reader)?,
42            self.document.get(&self.reader)?,
43            self.html.get(&self.reader)?,
44        ))
45    }
46    /// # Errors
47    #[inline]
48    pub fn get_document(&self) -> Result<Document, ReadError> {
49        self.document.get(&self.reader)
50    }
51
52    /// # Errors
53    #[inline]
54    #[allow(clippy::future_not_send)]
55    pub async fn get_document_async<A: AsyncEngine>(&self) -> Result<Document, ReadError> {
56        self.document.get_async::<A, _>(&self.reader).await
57    }
58
59    /// # Errors
60    #[inline]
61    pub fn get_html(&self) -> Result<Box<str>, ReadError> {
62        self.html.get(&self.reader)
63    }
64
65    /// # Errors
66    #[inline]
67    pub fn get_css(&self) -> Box<[Css]> {
68        self.css.get().clone()
69    }
70
71    /// # Errors
72    pub fn get_html_body(&self) -> Result<Box<str>, ReadError> {
73        self.get_html_range(*self.body.get())
74    }
75
76    /// # Errors
77    pub fn get_html_body_inner(&self) -> Result<Box<str>, ReadError> {
78        let mut range = *self.body.get();
79        range.start += *self.inner_offset.get() as usize;
80        range.end -= "</body>".len();
81        self.get_html_range(range)
82    }
83
84    /// # Errors
85    #[inline]
86    pub fn get_html_range(&self, range: DocumentRange) -> Result<Box<str>, ReadError> {
87        self.html.get_range(&self.reader, range.start, range.end)
88    }
89
90    /// # Errors
91    #[inline]
92    pub fn get_data<T: bincode::de::Decode<()>>(
93        &self,
94        start: usize,
95        end: usize,
96    ) -> Result<T, ReadError> {
97        self.data.deserialize_range(&self.reader, start, end) //.get_range(&self.reader, start, end)
98    }
99
100    /// # Errors
101    pub fn from_file(path: PathBuf) -> Result<Self, ReadError> {
102        let data = BytesField;
103        let document = LazyField::default();
104        let html = StreamField;
105        let (reader, (body, css, inner_offset)) = LazyFile::new_and_then(path, |mut reader| {
106            let body = EagerField::new(&mut reader)?;
107            let inner_offset = EagerField::new(&mut reader)?;
108            let css = EagerField::new(&mut reader)?;
109            Ok((body, css, inner_offset))
110        })?;
111        Ok(Self {
112            reader,
113            body,
114            inner_offset,
115            css,
116            data,
117            document,
118            html,
119        })
120    }
121}
122#[cfg(feature = "deepsize")]
123impl deepsize::DeepSizeOf for DocumentFile {
124    fn deep_size_of_children(&self, context: &mut deepsize::Context) -> usize {
125        self.css
126            .get()
127            .iter()
128            .map(|c| match c {
129                Css::Class { name, css } => name.len() + css.len(),
130                Css::Inline(s) | Css::Link(s) => s.len(),
131            })
132            .sum::<usize>()
133            + self.document.deep_size_of_children(context)
134    }
135}