Added capturing to Pairs.
@@ -11,6 +11,7 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::ptr;
use std::rc::Rc;
+use std::str;
use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
@@ -43,6 +44,69 @@ pub fn new<R: RuleType>(
}
impl<'i, R: RuleType> Pairs<'i, R> {
+ /// Captures a slice from the `&str` defined by the starting position of the first token `Pair`
+ /// and the ending position of the last token `Pair` of the `Pairs`. This also captures
+ /// the input between those two token `Pair`s.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use std::rc::Rc;
+ /// # use pest;
+ /// # #[allow(non_camel_case_types)]
+ /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ /// enum Rule {
+ /// a,
+ /// b
+ /// }
+ ///
+ /// let input = "a b";
+ /// let pairs = pest::state(input, |state| {
+ /// // generating Token pairs with Rule::a and Rule::b ...
+ /// # state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
+ /// # .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
+ /// }).unwrap();
+ ///
+ /// assert_eq!(pairs.as_str(), "a b");
+ /// ```
+ #[inline]
+ pub fn as_str(&self) -> &'i str {
+ let start = self.pos(self.start);
+ let end = self.pos(self.end - 1);
+
+ // Generated positions always come from Positions and are UTF-8 borders.
+ unsafe { str::from_utf8_unchecked(&self.input[start..end]) }
+ }
+
+ /// Captures inner token `Pair`s and concatenates resulting `&str`s. This does not capture
+ /// the input between token `Pair`s.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use std::rc::Rc;
+ /// # use pest;
+ /// # #[allow(non_camel_case_types)]
+ /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ /// enum Rule {
+ /// a,
+ /// b
+ /// }
+ ///
+ /// let input = "a b";
+ /// let pairs = pest::state(input, |state| {
+ /// // generating Token pairs with Rule::a and Rule::b ...
+ /// # state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
+ /// # .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
+ /// }).unwrap();
+ ///
+ /// assert_eq!(pairs.concat(), "ab");
+ /// ```
+ #[inline]
+ pub fn concat(&self) -> String {
+ self.clone().into_iter().fold(String::new(), |string, pair| string + pair.as_str())
+ }
+
/// Flattens the `Pairs`.
///
/// # Examples
@@ -117,6 +181,14 @@ impl<'i, R: RuleType> Pairs<'i, R> {
_ => unreachable!()
}
}
+
+ fn pos(&self, index: usize) -> usize {
+ match self.queue[index] {
+ QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
+ input_pos
+ }
+ }
+ }
}
impl<'i, R: RuleType> Iterator for Pairs<'i, R> {
