flams_ontology/narration/
documents.rs

1use super::{
2    checking::DocumentChecker, paragraphs::ParagraphKind, sections::SectionLevel, DocumentElement,
3    NarrationTrait,
4};
5use crate::{
6    uris::{DocumentURI, Name},
7    Checked, CheckingState, Resolvable, Unchecked,
8};
9use core::str;
10use flams_utils::prelude::{TreeChild, TreeChildIter, TreeLike};
11use std::{borrow::Cow, fmt::Debug, str::FromStr};
12use triomphe::Arc;
13
14#[derive(Debug, Clone, Default)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct DocumentStyles {
17    pub counters: Vec<SectionCounter>,
18    pub styles: Vec<DocumentStyle>,
19}
20
21#[derive(Debug, Clone)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub struct DocumentStyle {
24    pub kind: ParagraphKind,
25    pub name: Option<Name>,
26    pub counter: Option<Name>,
27}
28impl FromStr for DocumentStyle {
29    type Err = ();
30    fn from_str(s: &str) -> Result<Self, Self::Err> {
31        if let Some((a, b)) = s.split_once('-') {
32            let kind = ParagraphKind::from_str(a)?;
33            let name = Some(Name::from_str(b).map_err(|_| ())?);
34            return Ok(Self {
35                kind,
36                name,
37                counter: None,
38            });
39        }
40        let kind = ParagraphKind::from_str(s)?;
41        Ok(Self {
42            kind,
43            name: None,
44            counter: None,
45        })
46    }
47}
48
49#[derive(Debug, Clone)]
50#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51pub struct SectionCounter {
52    pub name: Name,
53    pub parent: Option<SectionLevel>,
54}
55
56#[derive(Debug)]
57pub struct OpenDocument<State: CheckingState> {
58    pub uri: DocumentURI,
59    pub title: Option<Box<str>>,
60    pub elements: State::Seq<DocumentElement<State>>,
61    pub styles: DocumentStyles,
62}
63crate::serde_impl! {mod serde_doc =
64    struct OpenDocument[uri,title,elements,styles]
65}
66
67#[derive(Debug, Clone)]
68pub struct Document(pub(super) Arc<OpenDocument<Checked>>);
69impl Resolvable for Document {
70    type From = DocumentURI;
71    #[inline]
72    fn id(&self) -> Cow<'_, Self::From> {
73        Cow::Borrowed(&self.0.uri)
74    }
75}
76impl Document {
77    #[inline]
78    #[must_use]
79    pub fn uri(&self) -> &DocumentURI {
80        &self.0.uri
81    }
82    #[must_use]
83    pub fn strong_count(&self) -> usize {
84        Arc::strong_count(&self.0)
85    }
86    #[inline]
87    #[must_use]
88    pub fn title(&self) -> Option<&str> {
89        self.0.title.as_deref()
90    }
91    #[inline]
92    #[must_use]
93    pub fn styles(&self) -> &DocumentStyles {
94        &self.0.styles
95    }
96    #[inline]
97    pub fn dfs(&self) -> impl Iterator<Item = &DocumentElement<Checked>> {
98        <_ as TreeChildIter<Self>>::dfs(NarrationTrait::children(self).iter())
99    }
100}
101
102impl NarrationTrait for Document {
103    #[inline]
104    fn children(&self) -> &[DocumentElement<Checked>] {
105        &self.0.elements
106    }
107    #[inline]
108    fn from_element(_: &DocumentElement<Checked>) -> Option<&Self>
109    where
110        Self: Sized,
111    {
112        None
113    }
114}
115
116impl NarrationTrait for OpenDocument<Checked> {
117    #[inline]
118    fn children(&self) -> &[DocumentElement<Checked>] {
119        &self.elements
120    }
121    #[inline]
122    fn from_element(_: &DocumentElement<Checked>) -> Option<&Self>
123    where
124        Self: Sized,
125    {
126        None
127    }
128}
129
130#[cfg(feature = "serde")]
131mod serde_impl {
132    impl serde::Serialize for super::Document {
133        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
134        where
135            S: serde::Serializer,
136        {
137            self.0.serialize(serializer)
138        }
139    }
140}
141
142pub type UncheckedDocument = OpenDocument<Unchecked>;
143
144impl UncheckedDocument {
145    #[inline]
146    pub fn dfs(&self) -> impl Iterator<Item = &DocumentElement<Unchecked>> {
147        <_ as TreeChildIter<Self>>::dfs(self.elements.iter())
148    }
149    pub fn check(self, checker: &mut impl DocumentChecker) -> Document {
150        let elements = super::checking::DocumentCheckIter::go(self.elements, checker, &self.uri)
151            .into_boxed_slice();
152        Document(Arc::new(OpenDocument {
153            uri: self.uri,
154            title: self.title,
155            styles: self.styles,
156            elements,
157        }))
158    }
159
160    /*
161    /// #### Errors
162    pub fn from_byte_stream(bytes: &mut impl BinaryReader) -> Result<Self, DecodeError> {
163        let version = bytes.pop()?;
164        let uri = bytes.read_string(DocumentURI::from_str)??;
165        let title: Option<Box<str>> =
166            bytes.read_string(|s| if s.is_empty() { None } else { Some(s.into()) })?;
167        let elements = ByteReadState::new(bytes,version).go()?;
168        Ok(Self {
169            uri,
170            title,
171            elements,
172        })
173    }
174     */
175}
176
177impl TreeLike for Document {
178    type Child<'a> = &'a DocumentElement<Checked>;
179    type RefIter<'a> = std::slice::Iter<'a, DocumentElement<Checked>>;
180    fn children(&self) -> Option<Self::RefIter<'_>> {
181        Some(NarrationTrait::children(self).iter())
182    }
183}
184impl<'a> TreeChild<Document> for &'a DocumentElement<Checked> {
185    fn children<'b>(&self) -> Option<std::slice::Iter<'a, DocumentElement<Checked>>>
186    where
187        Self: 'b,
188    {
189        Some(NarrationTrait::children(*self).iter())
190    }
191}
192
193impl TreeLike for UncheckedDocument {
194    type Child<'a> = &'a DocumentElement<Unchecked>;
195    type RefIter<'a> = std::slice::Iter<'a, DocumentElement<Unchecked>>;
196    fn children(&self) -> Option<Self::RefIter<'_>> {
197        Some(self.elements.iter())
198    }
199}
200impl<'a> TreeChild<UncheckedDocument> for &'a DocumentElement<Unchecked> {
201    fn children<'b>(&self) -> Option<std::slice::Iter<'a, DocumentElement<Unchecked>>>
202    where
203        Self: 'b,
204    {
205        match self {
206            DocumentElement::Section(s) => Some(s.children.iter()),
207            DocumentElement::Paragraph(p) => Some(p.children.iter()),
208            DocumentElement::Problem(e) => Some(e.children.iter()),
209            DocumentElement::Module { children, .. }
210            | DocumentElement::Morphism { children, .. }
211            | DocumentElement::MathStructure { children, .. }
212            | DocumentElement::Extension { children, .. }
213            | DocumentElement::SkipSection(children)
214            | DocumentElement::Slide { children, .. } => Some(children.iter()),
215            _ => None,
216        }
217    }
218}
219
220/*
221impl<State:CheckingState> OpenDocument<State> {
222    /// #### Errors
223    pub fn into_byte_stream(&self,bytes: &mut impl BinaryWriter) -> Result<(),std::io::Error> {
224        bytes.write_all(&[1])?;
225        bytes.write_string(&self.uri.to_string())?;
226        bytes.write_string(self.title.as_ref().map_or("",|b| &**b))?;
227        for e in &self.elements {
228            match e {
229                DocumentElement::SetSectionLevel(lvl) => {
230                    bytes.write_all(&[0,lvl.into()])?;
231                },
232                DocumentElement::Section(s) => {
233                    // 1
234                    todo!()
235                }
236                DocumentElement::Module { range, module, children } => {
237                    // 2
238                    todo!()
239                }
240                DocumentElement::Morphism { range, morphism, children } => {
241                    // 3
242                    todo!()
243                }
244                DocumentElement::MathStructure { range, structure, children } => {
245                    // 4
246                    todo!()
247                }
248                DocumentElement::DocumentReference { id, range, target } => {
249                    // 5
250                    todo!()
251                }
252                DocumentElement::SymbolDeclaration(s) => {
253                    // 6
254                    todo!()
255                }
256                DocumentElement::Notation { symbol, id, notation } => {
257                    // 7
258                    todo!()
259                }
260                DocumentElement::VariableNotation { variable, id, notation } => {
261                    // 8
262                    todo!()
263                }
264                DocumentElement::Variable(v) => {
265                    // 9
266                    todo!()
267                }
268                DocumentElement::Definiendum { range, uri } => {
269                    // 10
270                    todo!()
271                }
272                DocumentElement::SymbolReference { range, uri, notation } => {
273                    // 11
274                    todo!()
275                }
276                DocumentElement::VariableReference { range, uri, notation } => {
277                    // 12
278                    todo!()
279                }
280                DocumentElement::TopTerm { uri, term } => {
281                    // 13
282                    todo!()
283                }
284                DocumentElement::UseModule(uri) => {
285                    // 14
286                    todo!()
287                }
288                DocumentElement::ImportModule(uri) => {
289                    // 15
290                    todo!()
291                }
292                DocumentElement::Paragraph(p) => {
293                    // 16
294                    todo!()
295                }
296                DocumentElement::Problem(e) => {
297                    // 17
298                    todo!()
299                }
300            }
301        }
302        Ok(())
303    }
304}
305*/
306/*
307#[allow(clippy::type_complexity)]
308struct ByteReadState<'a, B: BinaryReader> {
309    stack: Vec<(
310        DocumentElement<Unchecked>,
311        Vec<DocumentElement<Unchecked>>,
312        u16,
313        u16,
314    )>,
315    curr: Vec<DocumentElement<Unchecked>>,
316    max: u16,
317    idx: u16,
318    version:u8,
319    bytes: &'a mut B,
320}
321impl<'a, B: BinaryReader> ByteReadState<'a, B> {
322    fn new(bytes: &'a mut B,version:u8) -> Self {
323        Self {
324            stack: Vec::new(),
325            curr: Vec::new(),
326            max: 0,
327            idx: 0,
328            version,
329            bytes,
330        }
331    }
332
333    fn do_elem(&mut self) -> Result<(), DecodeError> {
334        match self.bytes.pop()? {
335      0 /*SetSectionLevel*/ => if let Ok(s) = self.bytes.pop()?.try_into() {
336          self.curr.push(DocumentElement::SetSectionLevel(s));
337          Ok(())
338        } else {
339          Err(DecodeError::UnknownDiscriminant)
340        },
341      1 /*Section*/ => todo!(),
342      2 /*Module*/ => todo!(),
343      3 /*Morphism*/ => todo!(),
344      4 /*MathStructure*/ => todo!(),
345      5 /*DocumentReference*/ => todo!(),
346      6 /*SymbolDeclaration*/ => todo!(),
347      7 /*Notation*/ => todo!(),
348      8 /*VariableNotation*/ => todo!(),
349      9 /*Variable*/ => todo!(),
350      10 /*Definiendum*/ => todo!(),
351      11 /*SymbolReference*/ => todo!(),
352      12 /*VariableReference*/ => todo!(),
353      13 /*TopTerm*/ => todo!(),
354      14 /*UseModule*/ => todo!(),
355      15 /*ImportModule*/ => todo!(),
356      16 /*Paragraph*/ => todo!(),
357      17 /*Problem*/ => todo!(),
358      _ => Err(DecodeError::UnknownDiscriminant)
359    }
360    }
361
362    fn go(mut self) -> Result<Vec<DocumentElement<Unchecked>>, DecodeError> {
363        self.max = self.bytes.read_u16()?;
364        loop {
365            while self.idx < self.max {
366                self.idx += 1;
367                self.do_elem()?;
368            }
369            if let Some((mut last, next, idx, max)) = self.stack.pop() {
370                let done = std::mem::replace(&mut self.curr, next);
371                last.set_children(done).unwrap_or_else(|_| unreachable!());
372                self.curr.push(last);
373                self.idx = idx;
374                self.max = max;
375            } else {
376                return Ok(self.curr);
377            }
378        }
379    }
380    /*
381    #[cfg(feature="tokio")]
382    async fn go_async(&mut self,bytes:&mut impl flams_utils::binary::AsyncBinaryReader) -> Result<Vec<UncheckedDocumentElement>,DecodeError> {
383      use tokio::io::{AsyncBufRead,AsyncBufReadExt,AsyncRead,AsyncReadExt};
384      match bytes.read_u8().await? {
385        0 => todo!(),
386        1 => todo!(),
387        2 => todo!(),
388        _ => return Err(DecodeError::UnknownDiscriminant)
389      }
390    }
391    */
392}
393 */