pub struct NodeRule { /* private fields */ }Expand description
Layout rules for one node kind.
A node rule can make the node a group (laid out on one line if it fits, broken at its line opportunities otherwise), indent its contents, ask for spacing before and after the node, name the delimiters and separator of a list, cap the blank lines kept inside it, and carry token rules for its direct child tokens.
§Examples
use fmt_lang::{Indent, NodeRule, Space, Trailing};
// A JSON object: `{ "a": 1, "b": 2 }` when it fits, one member per line
// (indented) when it does not, and no trailing comma.
let object = NodeRule::new("object")
.group()
.indent(Indent::Block)
.delimiters("{", "}", Space::Line)
.separator(",", Space::Line, Trailing::Never);Implementations§
Source§impl NodeRule
impl NodeRule
Sourcepub fn new(kind: impl Into<String>) -> Self
pub fn new(kind: impl Into<String>) -> Self
A rule for nodes of the kind named kind, with nothing set yet.
§Examples
use fmt_lang::NodeRule;
let stmt = NodeRule::new("stmt");Sourcepub fn indent(self, indent: Indent) -> Self
pub fn indent(self, indent: Indent) -> Self
Sets how the node indents its contents (by Rules::indent columns).
§Examples
use fmt_lang::{Indent, NodeRule};
let binary = NodeRule::new("binary").indent(Indent::Hanging);Sourcepub fn before(self, space: Space) -> Self
pub fn before(self, space: Space) -> Self
Spacing in the gap before the node (before its first token).
§Examples
use fmt_lang::{NodeRule, Space};
// Every statement starts a new line.
let stmt = NodeRule::new("stmt").before(Space::Hard);Sourcepub fn after(self, space: Space) -> Self
pub fn after(self, space: Space) -> Self
Spacing in the gap after the node (after its last token).
§Examples
use fmt_lang::{NodeRule, Space};
let stmt = NodeRule::new("stmt").after(Space::Hard);Sourcepub fn delimiters(
self,
open: impl Into<String>,
close: impl Into<String>,
inner: Space,
) -> Self
pub fn delimiters( self, open: impl Into<String>, close: impl Into<String>, inner: Space, ) -> Self
Names the node’s delimiter tokens and the spacing just inside them (after
open and before close). An empty body (open immediately followed by
close) gets Space::None unless empty says
otherwise.
A delimiter is recognised only as the node’s first (for open) or last
(for close) significant direct child, so the same kinds may appear
elsewhere inside the node without confusion.
§Examples
use fmt_lang::{NodeRule, Space};
// `[1, 2]` flat, or one element per line when broken.
let array = NodeRule::new("array").group().delimiters("[", "]", Space::SoftLine);Sourcepub fn empty(self, space: Space) -> Self
pub fn empty(self, space: Space) -> Self
Spacing between the delimiters when the body is empty. Has no effect
unless delimiters is set (before or after this
call).
§Examples
use fmt_lang::{NodeRule, Space};
// `{ }` rather than `{}` for an empty block.
let block = NodeRule::new("block").delimiters("{", "}", Space::Hard).empty(Space::Single);Sourcepub fn separator(
self,
kind: impl Into<String>,
after: Space,
trailing: Trailing,
) -> Self
pub fn separator( self, kind: impl Into<String>, after: Space, trailing: Trailing, ) -> Self
Names the list separator among the node’s direct child tokens, the
spacing after it (before it is Space::None), and what to do with a
trailing one.
§Examples
use fmt_lang::{NodeRule, Space, Trailing};
let args = NodeRule::new("args").separator(",", Space::Line, Trailing::Preserve);Sourcepub fn separator_text(self, text: impl Into<String>) -> Self
pub fn separator_text(self, text: impl Into<String>) -> Self
The text written when Trailing::Always adds a separator. Defaults to
the separator’s kind name, which is its text in languages (such as
those forged by lang-forge) that name symbol tokens by their text. Has
no effect without a separator.
§Examples
use fmt_lang::{NodeRule, Space, Trailing};
let list = NodeRule::new("list")
.delimiters("(", ")", Space::SoftLine)
.separator("COMMA", Space::Line, Trailing::Always)
.separator_text(",");Sourcepub fn blank_lines(self, max: u8) -> Self
pub fn blank_lines(self, max: u8) -> Self
Caps the blank lines kept between lines inside this node (overrides
Rules::max_blank_lines here).
§Examples
use fmt_lang::NodeRule;
// No blank lines inside an argument list.
let args = NodeRule::new("args").blank_lines(0);Sourcepub fn token(self, rule: TokenRule) -> Self
pub fn token(self, rule: TokenRule) -> Self
Adds a token rule for the node’s direct child tokens. It wins over a
top-level Rules::token rule for the same side.
§Examples
use fmt_lang::{NodeRule, Space, TokenRule};
let member = NodeRule::new("member").token(TokenRule::new(":").before(Space::None).after(Space::Single));Sourcepub fn optional(self) -> Self
pub fn optional(self) -> Self
Marks the rule optional: dropped by Rules::compile if the language
lacks any kind it names, instead of an error.
§Examples
use fmt_lang::{NodeRule, Rules, Space};
let rules = Rules::new().node(NodeRule::new("block").before(Space::Hard).optional());
let style = rules.compile(|_| None::<u8>)?; // no `block` here: dropped