use std::iter::FromIterator;
pub mod ast;
pub mod code;
pub mod text;
use self::ast::Ast;
use crate::parser::Printer;
#[derive(Debug)]
pub struct Document<'a> {
tree: Ast<'a>,
}
impl<'a> Document<'a> {
pub(crate) fn new(tree: Ast<'a>) -> Self {
Document { tree }
}
pub fn print_docs<P: Printer>(&self, printer: &P) -> String {
self.tree.print_docs(printer)
}
pub fn print_code(
&self,
entrypoint: Option<&str>,
language: Option<&str>,
) -> Result<String, CompileError> {
self.tree.print_code(entrypoint, language)
}
}
impl<'a, T> FromIterator<T> for Document<'a>
where
Ast<'a>: FromIterator<T>,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self::new(iter.into_iter().collect())
}
}
impl<'a, T> From<T> for Document<'a>
where
Ast<'a>: From<T>,
{
fn from(value: T) -> Self {
Self::new(value.into())
}
}
#[derive(Debug)]
pub enum CompileErrorKind {
UnknownMetaVariable(String),
UnknownMacro(String),
MissingEntrypoint,
}
#[derive(Debug)]
pub enum CompileError {
#[doc(hidden)]
Multi(Vec<CompileError>),
#[doc(hidden)]
Single {
line_number: usize,
kind: CompileErrorKind,
},
}
impl std::fmt::Display for CompileError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CompileError::Multi(errors) => {
for error in errors {
writeln!(f, "{}", error)?;
}
Ok(())
}
CompileError::Single { line_number, kind } => {
writeln!(f, "{:?} (line {})", kind, line_number)
}
}
}
}
impl std::error::Error for CompileError {}
impl FromIterator<CompileError> for CompileError {
fn from_iter<I: IntoIterator<Item = CompileError>>(iter: I) -> Self {
CompileError::Multi(iter.into_iter().collect())
}
}