outline/document/
mod.rs

1//! The internal representation of a literate document
2use std::iter::FromIterator;
3
4pub mod ast;
5pub mod code;
6pub mod text;
7
8use self::ast::Ast;
9use crate::parser::Printer;
10
11/// A representation of a `Document` of literate code
12#[derive(Debug)]
13pub struct Document<'a> {
14    tree: Ast<'a>,
15}
16
17impl<'a> Document<'a> {
18    /// Creates a new document with the tree
19    pub(crate) fn new(tree: Ast<'a>) -> Self {
20        Document { tree }
21    }
22
23    /// Formats this `Document` as a string containing the documentation file contents
24    pub fn print_docs<P: Printer>(&self, printer: &P) -> String {
25        self.tree.print_docs(printer)
26    }
27
28    /// Formats this `Document` as a string containing the compiled code
29    pub fn print_code(
30        &self,
31        entrypoint: Option<&str>,
32        language: Option<&str>,
33    ) -> Result<String, CompileError> {
34        self.tree.print_code(entrypoint, language)
35    }
36}
37
38impl<'a, T> FromIterator<T> for Document<'a>
39where
40    Ast<'a>: FromIterator<T>,
41{
42    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
43        Self::new(iter.into_iter().collect())
44    }
45}
46
47impl<'a, T> From<T> for Document<'a>
48where
49    Ast<'a>: From<T>,
50{
51    fn from(value: T) -> Self {
52        Self::new(value.into())
53    }
54}
55
56/// Problems encountered while compiling the document
57#[derive(Debug)]
58pub enum CompileErrorKind {
59    /// An unknown meta variable was encountered
60    UnknownMetaVariable(String),
61    /// An unknown macro name was encountered
62    UnknownMacro(String),
63    /// There is no unnamed code block to use as the entrypoint
64    MissingEntrypoint,
65}
66
67/// Errors that were encountered while compiling the document
68#[derive(Debug)]
69pub enum CompileError {
70    #[doc(hidden)]
71    Multi(Vec<CompileError>),
72    #[doc(hidden)]
73    Single {
74        line_number: usize,
75        kind: CompileErrorKind,
76    },
77}
78
79impl std::fmt::Display for CompileError {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        match self {
82            CompileError::Multi(errors) => {
83                for error in errors {
84                    writeln!(f, "{}", error)?;
85                }
86                Ok(())
87            }
88            CompileError::Single { line_number, kind } => {
89                writeln!(f, "{:?} (line {})", kind, line_number)
90            }
91        }
92    }
93}
94
95impl std::error::Error for CompileError {}
96
97impl FromIterator<CompileError> for CompileError {
98    fn from_iter<I: IntoIterator<Item = CompileError>>(iter: I) -> Self {
99        CompileError::Multi(iter.into_iter().collect())
100    }
101}