pub struct PairsBuilder<'i, R> { /* private fields */ }Expand description
A builder that constructs Pairs manually, without running a parser.
This is meant for unit tests: code that consumes parser output often takes a
Pair or Pairs as input, and testing it would otherwise require
running a real parse just to obtain the right shape of tokens. With a
PairsBuilder the expected tree can be spelled out directly.
A pair is described by a Rule, a start byte offset and an end byte
offset into input (the same [start, end) convention used by
Span), and, optionally, inner pairs and a node tag.
§Examples
Building a single leaf pair — the motivating use case, a Pair handed to a
function under test without invoking the parser:
enum Rule {
integer,
}
let pairs = PairsBuilder::new("42").rule(Rule::integer, 0, 2).build();
let pair = pairs.peek().unwrap();
assert_eq!(pair.as_rule(), Rule::integer);
assert_eq!(pair.as_str(), "42");Nesting inner pairs with rule_with and attaching tags with tag:
enum Rule {
sum,
number,
}
// Describes the parse tree of "1+2": a `sum` containing two `number`s.
let pairs = PairsBuilder::new("1+2")
.rule_with(Rule::sum, 0, 3, |inner| {
inner
.rule(Rule::number, 0, 1)
.tag("lhs")
.rule(Rule::number, 2, 3)
.tag("rhs")
})
.build();
let sum = pairs.peek().unwrap();
assert_eq!(sum.as_rule(), Rule::sum);
let numbers: Vec<_> = sum.into_inner().map(|p| p.as_str()).collect();
assert_eq!(numbers, ["1", "2"]);Implementations§
Source§impl<'i, R: RuleType> PairsBuilder<'i, R>
impl<'i, R: RuleType> PairsBuilder<'i, R>
Sourcepub fn rule_with<F>(
self,
rule: R,
start: usize,
end: usize,
build_children: F,
) -> Self
pub fn rule_with<F>( self, rule: R, start: usize, end: usize, build_children: F, ) -> Self
Appends a Pair for rule spanning input[start..end], whose inner
Pairs are produced by build_children.
build_children receives a fresh builder over the same input; the
pairs it appends become the inner pairs of this rule, in the order they
are added.
§Examples
let pairs = PairsBuilder::new("[a,b]")
.rule_with(Rule::list, 0, 5, |inner| {
inner.rule(Rule::item, 1, 2).rule(Rule::item, 3, 4)
})
.build();
let list = pairs.peek().unwrap();
assert_eq!(list.into_inner().count(), 2);Sourcepub fn tag(self, tag: &'i str) -> Self
pub fn tag(self, tag: &'i str) -> Self
Attaches tag to the most recently appended pair, so that it can be
looked up with Pairs::find_first_tagged, Pairs::find_tagged or
Pair::as_node_tag.
§Panics
Panics if called before any rule has been appended to this builder.
§Examples
let pairs = PairsBuilder::new("7").rule(Rule::number, 0, 1).tag("answer").build();
assert_eq!(pairs.find_first_tagged("answer").unwrap().as_str(), "7");Sourcepub fn build(self) -> Pairs<'i, R> ⓘ
pub fn build(self) -> Pairs<'i, R> ⓘ
Consumes the builder and produces the Pairs.
§Panics
Panics if any appended rule’s [start, end) is not a valid range into
input — that is, if start > end, end is past the end of input, or
either offset does not fall on a UTF-8 character boundary. This mirrors
the invariant enforced by Span::new, which the resulting pairs would
otherwise violate.