cairo_lang_formatter/
lib.rspub mod cairo_formatter;
pub mod formatter_impl;
pub mod node_properties;
use cairo_lang_diagnostics::DiagnosticsBuilder;
use cairo_lang_filesystem::ids::{FileKind, FileLongId, VirtualFile};
use cairo_lang_parser::parser::Parser;
use cairo_lang_syntax::node::db::SyntaxGroup;
use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
use cairo_lang_utils::Intern;
use serde::{Deserialize, Serialize};
pub use crate::cairo_formatter::{CairoFormatter, FormatOutcome, StdinFmt};
use crate::formatter_impl::FormatterImpl;
#[cfg(test)]
mod test;
pub const CAIRO_FMT_IGNORE: &str = ".cairofmtignore";
pub fn get_formatted_file(
db: &dyn SyntaxGroup,
syntax_root: &SyntaxNode,
config: FormatterConfig,
) -> String {
let mut formatter = FormatterImpl::new(db, config);
formatter.get_formatted_string(syntax_root)
}
pub fn format_string(db: &dyn SyntaxGroup, content: String) -> String {
let virtual_file = FileLongId::Virtual(VirtualFile {
parent: None,
name: "string_to_format".into(),
content: content.clone().into(),
code_mappings: [].into(),
kind: FileKind::Module,
})
.intern(db);
let mut diagnostics = DiagnosticsBuilder::default();
let syntax_root =
Parser::parse_file(db, &mut diagnostics, virtual_file, content.as_str()).as_syntax_node();
get_formatted_file(db, &syntax_root, FormatterConfig::default())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CollectionsBreakingBehavior {
SingleBreakPoint,
LineByLine,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FormatterConfig {
tab_size: usize,
max_line_length: usize,
sort_module_level_items: bool,
tuple_breaking_behavior: CollectionsBreakingBehavior,
fixed_array_breaking_behavior: CollectionsBreakingBehavior,
merge_use_items: bool,
allow_duplicate_uses: bool,
}
const TAB_SIZE: usize = 4;
const MAX_LINE_LENGTH: usize = 100;
impl FormatterConfig {
pub fn new(
tab_size: usize,
max_line_length: usize,
sort_module_level_items: bool,
tuple_breaking_behavior: CollectionsBreakingBehavior,
fixed_array_breaking_behavior: CollectionsBreakingBehavior,
merge_use_items: bool,
allow_duplicate_uses: bool,
) -> Self {
Self {
tab_size,
max_line_length,
sort_module_level_items,
tuple_breaking_behavior,
fixed_array_breaking_behavior,
merge_use_items,
allow_duplicate_uses,
}
}
pub fn sort_module_level_items(mut self, sort_module_level_items: bool) -> Self {
self.sort_module_level_items = sort_module_level_items;
self
}
pub fn tuple_breaking_behavior(mut self, behavior: CollectionsBreakingBehavior) -> Self {
self.tuple_breaking_behavior = behavior;
self
}
pub fn fixed_array_breaking_behavior(mut self, behavior: CollectionsBreakingBehavior) -> Self {
self.fixed_array_breaking_behavior = behavior;
self
}
pub fn merge_use_items(mut self, merge: bool) -> Self {
self.merge_use_items = merge;
self
}
pub fn allow_duplicate_uses(mut self, allow: bool) -> Self {
self.allow_duplicate_uses = allow;
self
}
}
impl Default for FormatterConfig {
fn default() -> Self {
Self {
tab_size: TAB_SIZE,
max_line_length: MAX_LINE_LENGTH,
sort_module_level_items: false,
tuple_breaking_behavior: CollectionsBreakingBehavior::LineByLine,
fixed_array_breaking_behavior: CollectionsBreakingBehavior::SingleBreakPoint,
merge_use_items: false,
allow_duplicate_uses: false,
}
}
}