1use std::iter::FromIterator;
3
4pub mod ast;
5pub mod code;
6pub mod text;
7
8use self::ast::Ast;
9use crate::parser::Printer;
10
11#[derive(Debug)]
13pub struct Document<'a> {
14 tree: Ast<'a>,
15}
16
17impl<'a> Document<'a> {
18 pub(crate) fn new(tree: Ast<'a>) -> Self {
20 Document { tree }
21 }
22
23 pub fn print_docs<P: Printer>(&self, printer: &P) -> String {
25 self.tree.print_docs(printer)
26 }
27
28 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#[derive(Debug)]
58pub enum CompileErrorKind {
59 UnknownMetaVariable(String),
61 UnknownMacro(String),
63 MissingEntrypoint,
65}
66
67#[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}