summaryrefslogtreecommitdiff
path: root/pest_consume
diff options
context:
space:
mode:
Diffstat (limited to 'pest_consume')
-rw-r--r--pest_consume/src/lib.rs103
1 files changed, 50 insertions, 53 deletions
diff --git a/pest_consume/src/lib.rs b/pest_consume/src/lib.rs
index 701fbba..425d8cf 100644
--- a/pest_consume/src/lib.rs
+++ b/pest_consume/src/lib.rs
@@ -6,8 +6,6 @@ use pest::RuleType;
pub use pest_consume_macros::match_inputs;
pub use pest_consume_macros::parser;
-static UNIT: () = ();
-
mod node {
use super::Parser;
use pest::error::{Error, ErrorVariant};
@@ -16,22 +14,22 @@ mod node {
use pest::{RuleType, Span};
/// Carries a pest Pair alongside custom user data.
- #[derive(Debug)]
- pub struct Node<'input, 'data, Rule: RuleType, Data> {
+ #[derive(Debug, Clone)]
+ pub struct Node<'input, Rule: RuleType, Data> {
pair: Pair<'input, Rule>,
- user_data: &'data Data,
+ user_data: Data,
}
/// Iterator over `Node`s. It is created by `Node::children` or `Nodes::new`.
- #[derive(Debug)]
- pub struct Nodes<'input, 'data, Rule: RuleType, Data> {
+ #[derive(Debug, Clone)]
+ pub struct Nodes<'input, Rule: RuleType, Data> {
pairs: Pairs<'input, Rule>,
span: Span<'input>,
- user_data: &'data Data,
+ user_data: Data,
}
- impl<'i, 'd, R: RuleType, D> Node<'i, 'd, R, D> {
- pub fn new(pair: Pair<'i, R>, user_data: &'d D) -> Self {
+ impl<'i, R: RuleType, D> Node<'i, R, D> {
+ pub fn new(pair: Pair<'i, R>, user_data: D) -> Self {
Node { pair, user_data }
}
/// Create an error that points to the span of the input.
@@ -42,14 +40,20 @@ mod node {
)
}
/// Reconstruct the input with a new pair, passing the user data along.
- pub fn with_pair(&self, new_pair: Pair<'i, R>) -> Self {
+ pub fn with_pair(&self, new_pair: Pair<'i, R>) -> Self
+ where
+ D: Clone,
+ {
Node {
pair: new_pair,
- user_data: self.user_data,
+ user_data: self.user_data.clone(),
}
}
/// If the contained pair has exactly one child, return a new Self containing it.
- pub fn single_child(&self) -> Option<Self> {
+ pub fn single_child(&self) -> Option<Self>
+ where
+ D: Clone,
+ {
let mut children = self.pair.clone().into_inner();
if let Some(child) = children.next() {
if children.next().is_none() {
@@ -61,7 +65,10 @@ mod node {
/// Return an iterator over the children of this input
// Can't use `-> impl Iterator` because of weird lifetime limitations
// (see https://github.com/rust-lang/rust/issues/61997).
- pub fn children(&self) -> Nodes<'i, 'd, R, D> {
+ pub fn children(&self) -> Nodes<'i, R, D>
+ where
+ D: Clone,
+ {
Nodes {
pairs: self.as_pair().clone().into_inner(),
span: self.as_span(),
@@ -69,8 +76,11 @@ mod node {
}
}
- pub fn user_data(&self) -> &'d D {
- self.user_data
+ pub fn user_data(&self) -> D
+ where
+ D: Clone,
+ {
+ self.user_data.clone()
}
pub fn as_pair(&self) -> &Pair<'i, R> {
&self.pair
@@ -93,13 +103,9 @@ mod node {
}
}
- impl<'i, 'd, R: RuleType, D> Nodes<'i, 'd, R, D> {
+ impl<'i, R: RuleType, D> Nodes<'i, R, D> {
/// `input` must be the _original_ input that `pairs` is pointing to.
- pub fn new(
- input: &'i str,
- pairs: Pairs<'i, R>,
- user_data: &'d D,
- ) -> Self {
+ pub fn new(input: &'i str, pairs: Pairs<'i, R>, user_data: D) -> Self {
let span = Span::new(input, 0, input.len()).unwrap();
Nodes {
pairs,
@@ -116,19 +122,27 @@ mod node {
}
pub fn aliased_rules<C>(&self) -> Vec<C::AliasedRule>
where
+ D: Clone,
C: Parser<Rule = R>,
<C as Parser>::Parser: PestParser<R>,
{
self.clone().map(|p| p.as_aliased_rule::<C>()).collect()
}
/// Reconstruct the input with a new pair, passing the user data along.
- fn with_pair(&self, new_pair: Pair<'i, R>) -> Node<'i, 'd, R, D> {
- Node::new(new_pair, self.user_data)
+ fn with_pair(&self, new_pair: Pair<'i, R>) -> Node<'i, R, D>
+ where
+ D: Clone,
+ {
+ Node::new(new_pair, self.user_data.clone())
}
}
- impl<'i, 'd, R: RuleType, D> Iterator for Nodes<'i, 'd, R, D> {
- type Item = Node<'i, 'd, R, D>;
+ impl<'i, R, D> Iterator for Nodes<'i, R, D>
+ where
+ R: RuleType,
+ D: Clone,
+ {
+ type Item = Node<'i, R, D>;
fn next(&mut self) -> Option<Self::Item> {
let child_pair = self.pairs.next()?;
@@ -137,34 +151,17 @@ mod node {
}
}
- impl<'i, 'd, R: RuleType, D> DoubleEndedIterator for Nodes<'i, 'd, R, D> {
+ impl<'i, R, D> DoubleEndedIterator for Nodes<'i, R, D>
+ where
+ R: RuleType,
+ D: Clone,
+ {
fn next_back(&mut self) -> Option<Self::Item> {
let child_pair = self.pairs.next_back()?;
let child = self.with_pair(child_pair);
Some(child)
}
}
-
- // Manual impl to avoid stupid `D: Clone` trait bound
- impl<'i, 'd, R: RuleType, D> Clone for Node<'i, 'd, R, D> {
- fn clone(&self) -> Self {
- Node {
- pair: self.pair.clone(),
- user_data: self.user_data,
- }
- }
- }
-
- // Manual impl to avoid stupid `D: Clone` trait bound
- impl<'i, 'd, R: RuleType, D> Clone for Nodes<'i, 'd, R, D> {
- fn clone(&self) -> Self {
- Nodes {
- pairs: self.pairs.clone(),
- span: self.span.clone(),
- user_data: self.user_data,
- }
- }
- }
}
pub use node::{Node, Nodes};
@@ -183,16 +180,16 @@ pub trait Parser {
fn parse<'i>(
rule: Self::Rule,
input_str: &'i str,
- ) -> Result<Nodes<'i, 'static, Self::Rule, ()>, Error<Self::Rule>> {
- Self::parse_with_userdata(rule, input_str, &UNIT)
+ ) -> Result<Nodes<'i, Self::Rule, ()>, Error<Self::Rule>> {
+ Self::parse_with_userdata(rule, input_str, ())
}
/// Parses a `&str` starting from `rule`, carrying `user_data` through the parser methods.
- fn parse_with_userdata<'i, 'd, D>(
+ fn parse_with_userdata<'i, D>(
rule: Self::Rule,
input_str: &'i str,
- user_data: &'d D,
- ) -> Result<Nodes<'i, 'd, Self::Rule, D>, Error<Self::Rule>> {
+ user_data: D,
+ ) -> Result<Nodes<'i, Self::Rule, D>, Error<Self::Rule>> {
let pairs = Self::Parser::parse(rule, input_str)?;
Ok(Nodes::new(input_str, pairs, user_data))
}