mod build;
mod chars;
mod error;
mod lex;
mod logical;
#[cfg(test)]
mod oversize_tests;
mod render;
mod tree;
use vize_l0::{Allocator, Vec};
pub use error::{PugError, PugErrorCode};
pub use render::{PugHoleCounts, check_pug_fidelity, pug_hole_counts, render_pug};
pub use tree::{
PugAttr, PugAttrGroup, PugAttrItem, PugBlock, PugCall, PugCode, PugComment, PugDotBlock,
PugHtml, PugHtmlItem, PugInline, PugInterpolation, PugNode, PugRefusal, PugRefused, PugTag,
PugTagPart, PugText, PugTextPiece, PugTree, PugUnexpected,
};
pub fn parse_pug<'a>(
allocator: &'a Allocator,
source: &'a str,
) -> (PugTree<'a>, Vec<'a, PugError>) {
parse_pug_within(allocator, source, u32::MAX as usize)
}
fn parse_pug_within<'a>(
allocator: &'a Allocator,
source: &'a str,
limit: usize,
) -> (PugTree<'a>, Vec<'a, PugError>) {
let mut errors = Vec::new_in(&allocator);
if source.len() > limit {
errors.push(PugError {
code: PugErrorCode::SourceTooLarge,
offset: 0,
});
let eof = crate::markup::surface::Token::present(
source,
crate::slice::from(source, source.len()),
);
let tree = PugTree {
source,
nodes: Vec::new_in(&allocator),
eof,
};
return (tree, errors);
}
let logical = logical::Logical::new(allocator, source);
let mut tokens = Vec::new_in(&allocator);
let mut lex_errors = Vec::new_in(&allocator);
lex::lex(allocator, logical.text, &mut tokens, &mut lex_errors);
for &(code, at) in lex_errors.iter() {
errors.push(PugError {
code,
offset: logical.at(at as usize),
});
}
let tree = build::build(allocator, source, &logical, &tokens, &mut errors);
errors.sort_by_key(|error| error.offset);
debug_assert!(
check_pug_fidelity(&tree).is_ok(),
"pug L1 fidelity: render(tree) != source"
);
(tree, errors)
}