pub struct Rules { /* private fields */ }Expand description
A language’s formatting rules, as data.
Built with chained calls, then compiled against the
language’s kinds. An empty Rules formats nothing: every gap keeps its
original whitespace (trailing spaces at line ends and blank space at the
start and end of the file are still trimmed, and a final newline is added).
§Examples
use fmt_lang::{Indent, NodeRule, Rules, Space, TokenRule, Trailing};
let rules = Rules::new()
.indent(2)
.verbatim("ERROR")
.token(TokenRule::new(":").before(Space::None).after(Space::Single))
.node(
NodeRule::new("array")
.group()
.indent(Indent::Block)
.delimiters("[", "]", Space::SoftLine)
.separator(",", Space::Line, Trailing::Never),
);Implementations§
Source§impl Rules
impl Rules
Sourcepub fn new() -> Self
pub fn new() -> Self
No rules: indentation step 4, at most one blank line kept, indentation capped at 120 columns, a final newline.
§Examples
use fmt_lang::Rules;
let rules = Rules::new();
assert_eq!(rules, Rules::default());Sourcepub fn conventional() -> Self
pub fn conventional() -> Self
Conventional token spacing shared by most C-family languages, every
rule optional so the preset compiles against
any language:
- nothing before
,;)], one space after,and;; - nothing after
([; - one space around
===!=<=>=+=-=*=/=%=&&||=>->.
Operators that are also prefix operators in common languages (-,
+, *, &, !) and the angle brackets (<, >, generics in many
languages) are left out on purpose: spacing them needs node context,
which a NodeRule supplies.
§Examples
use fmt_lang::{NodeRule, Rules, Space};
let rules = Rules::conventional().node(NodeRule::new("stmt").before(Space::Hard));Sourcepub fn indent(self, columns: u8) -> Self
pub fn indent(self, columns: u8) -> Self
Columns per indentation level (default 4, at most
MAX_INDENT_STEP).
§Examples
use fmt_lang::Rules;
let rules = Rules::new().indent(2);Sourcepub fn max_indent(self, columns: u16) -> Self
pub fn max_indent(self, columns: u16) -> Self
The deepest indentation, in columns, the formatter will produce (default 120). Nesting past it stops adding indentation. This is the output budget against hostile input: without it, a file nested a million levels deep would format to terabytes of spaces.
§Examples
use fmt_lang::Rules;
let rules = Rules::new().max_indent(60);Sourcepub fn max_blank_lines(self, max: u8) -> Self
pub fn max_blank_lines(self, max: u8) -> Self
The most blank lines kept wherever a Space::Hard gap had blank
lines in the source (default 1). Gaps that keep their original
whitespace are not capped.
§Examples
use fmt_lang::Rules;
let rules = Rules::new().max_blank_lines(2);Sourcepub fn final_newline(self, yes: bool) -> Self
pub fn final_newline(self, yes: bool) -> Self
Whether non-empty output ends with a line break (default true).
§Examples
use fmt_lang::Rules;
let rules = Rules::new().final_newline(false);Sourcepub fn verbatim(self, kind: impl Into<String>) -> Self
pub fn verbatim(self, kind: impl Into<String>) -> Self
Names a node kind whose contents are always written exactly as in the
source, such as a parser’s error node ("ERROR" in languages forged by
lang-forge). Only the whitespace around such a node is formatted.
§Examples
use fmt_lang::Rules;
let rules = Rules::new().verbatim("ERROR").verbatim("raw_block");Sourcepub fn token(self, rule: TokenRule) -> Self
pub fn token(self, rule: TokenRule) -> Self
Adds a top-level token rule: a default for that token kind (or, with
TokenRule::any, for every token) wherever it appears.
§Examples
use fmt_lang::{Rules, Space, TokenRule};
let rules = Rules::new().token(TokenRule::new("+").around(Space::Single));Source§impl Rules
impl Rules
Sourcepub fn compile<K: Ord + Clone>(
&self,
resolve: impl FnMut(&str) -> Option<K>,
) -> Result<Style<K>, RuleError>
pub fn compile<K: Ord + Clone>( &self, resolve: impl FnMut(&str) -> Option<K>, ) -> Result<Style<K>, RuleError>
Resolves every kind name with resolve and compiles the rules into a
Style for that language.
resolve maps a name to the language’s kind, or None if the language
has no such kind. For a language forged by lang-forge it is
|name| lang.kind(name).
Later top-level token rules for the same kind refine earlier ones (a
side set later wins), so a preset such as Rules::conventional can be
adjusted by adding rules after it. The same holds for token rules within
one node rule.
§Errors
RuleError::UnknownKindif a non-optional rule names a kindresolvedoes not know.RuleError::DuplicateNodeif two node rules name the same kind.RuleError::IndentTooWideifRules::indentexceedsMAX_INDENT_STEP.RuleError::SeparatorIsDelimiterandRuleError::TrailingNeedsDelimitersfor inconsistent list rules.
§Examples
use fmt_lang::{NodeRule, Rules, Space};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
enum Kind { Stmt, Semi }
let style = Rules::new()
.node(NodeRule::new("stmt").before(Space::Hard))
.compile(|name| match name {
"stmt" => Some(Kind::Stmt),
";" => Some(Kind::Semi),
_ => None,
})?;