#![warn(missing_docs)]
#![forbid(unsafe_code)]
mod colored_writer;
mod error;
mod predoc;
mod pretty_simple;
mod lexer;
mod normalize;
mod parser;
mod pretty;
mod types;
pub use error::ParseError;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
use predoc::{Pretty, RenderConfig, render_with_config};
pub(crate) use error::Result;
pub(crate) use types::File;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct Options {
pub width: usize,
pub indent: usize,
}
impl Default for Options {
fn default() -> Self {
Self {
width: 100,
indent: 2,
}
}
}
#[doc(hidden)] pub fn parse(source: &str) -> Result<File> {
let mut parser = parser::Parser::new(source)?;
parser.parse_file()
}
#[doc(hidden)]
pub fn parse_normalized(source: &str) -> Result<File> {
let mut ast = parse(source)?;
normalize::normalize_file(&mut ast);
Ok(ast)
}
pub fn format(source: &str) -> Result<String> {
format_with(source, &Options::default())
}
pub fn format_with(source: &str, opts: &Options) -> Result<String> {
let ast = parse(source)?;
let mut doc = predoc::Doc::new();
ast.pretty(&mut doc);
let config = RenderConfig {
width: opts.width,
indent_width: opts.indent,
};
let output = render_with_config(doc, &config);
Ok(output)
}
pub(crate) fn ast_to_ir(ast: &File) -> predoc::IR {
let mut doc = predoc::Doc::new();
ast.pretty(&mut doc);
predoc::IR(predoc::fixup(doc))
}
#[doc(hidden)]
pub fn format_ast(source: &str) -> Result<String> {
use pretty_simple::PrettySimple;
let ast = parse(source)?;
let mut writer = colored_writer::ColoredWriter::new(source);
ast.format(&mut writer);
Ok(writer.finish())
}
#[doc(hidden)]
pub fn format_ir(source: &str) -> Result<String> {
use pretty_simple::PrettySimple;
let ast = parse(source)?;
let ir = ast_to_ir(&ast);
let mut writer = colored_writer::ColoredWriter::new(source);
ir.format(&mut writer);
Ok(writer.finish())
}
#[must_use]
pub fn format_error(source: &str, filename: Option<&str>, error: &ParseError) -> String {
let context = error::context::ErrorContext::new(source, filename);
let formatter = error::format::ErrorFormatter::new(&context);
formatter.format(error)
}
#[cfg(test)]
mod ast_format_tests;
#[cfg(test)]
mod ir_format_tests;
#[cfg(test)]
mod regression_tests;
#[cfg(test)]
mod tests_common;