@@ -22,14 +22,14 @@ pub const INPUT_CHARSET: &str = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVW
2222/// A token of the form `x(...)` or `x`
2323pub struct Tree < ' a > {
2424 /// The name `x`
25- pub name : & ' a str ,
25+ name : & ' a str ,
2626 /// Position one past the last character of the node's name. If it has
2727 /// children, the position of the '(' or '{'.
28- pub children_pos : usize ,
28+ children_pos : usize ,
2929 /// The type of parentheses surrounding the node's children.
30- pub parens : Parens ,
30+ parens : Parens ,
3131 /// The comma-separated contents of the `(...)`, if any
32- pub args : Vec < Tree < ' a > > ,
32+ args : Vec < Tree < ' a > > ,
3333}
3434
3535impl PartialEq for Tree < ' _ > {
@@ -79,6 +79,32 @@ pub trait FromTree: Sized {
7979}
8080
8181impl < ' a > Tree < ' a > {
82+ /// The name of this tree node.
83+ pub fn name ( & self ) -> & str { self . name }
84+
85+ /// The 0-indexed byte-position of the name in the original expression tree.
86+ pub fn name_pos ( & self ) -> usize { self . children_pos - self . name . len ( ) - 1 }
87+
88+ /// The 0-indexed byte-position of the '(' or '{' character which starts the
89+ /// expression's children.
90+ ///
91+ /// If the expression has no children, returns one past the end of the name.
92+ pub fn children_pos ( & self ) -> usize { self . children_pos - self . name . len ( ) - 1 }
93+
94+ /// The number of children this node has.
95+ pub fn n_children ( & self ) -> usize { self . args . len ( ) }
96+
97+ /// The type of parenthesis surrounding this node's children.
98+ ///
99+ /// If the node has no children, this will be `Parens::None`.
100+ pub fn parens ( & self ) -> Parens { self . parens }
101+
102+ /// An iterator over the direct children of this node.
103+ ///
104+ /// If you want to iterate recursively, use the [`TreeLike`] API which
105+ /// provides methods `pre_order_iter` and `post_order_iter`.
106+ pub fn children ( & self ) -> impl ExactSizeIterator < Item = & Self > { self . args . iter ( ) }
107+
82108 /// Split the name by a separating character.
83109 ///
84110 /// If the separator is present, returns the prefix before the separator and
@@ -260,20 +286,21 @@ impl<'a> Tree<'a> {
260286 & self ,
261287 mut map_child : F ,
262288 ) -> Result < Threshold < T , MAX > , E > {
289+ let mut child_iter = self . children ( ) ;
290+ let kchild = match child_iter. next ( ) {
291+ Some ( k) => k,
292+ None => return Err ( ParseThresholdError :: NoChildren . into ( ) ) ,
293+ } ;
263294 // First, special case "no arguments" so we can index the first argument without panics.
264- if self . args . is_empty ( ) {
265- return Err ( ParseThresholdError :: NoChildren . into ( ) ) ;
266- }
267-
268- if !self . args [ 0 ] . args . is_empty ( ) {
295+ if kchild. n_children ( ) > 0 {
269296 return Err ( ParseThresholdError :: KNotTerminal . into ( ) ) ;
270297 }
271298
272- let k = parse_num ( self . args [ 0 ] . name ) . map_err ( ParseThresholdError :: ParseK ) ? as usize ;
273- Threshold :: new ( k, vec ! [ ( ) ; self . args . len ( ) - 1 ] )
299+ let k = parse_num ( kchild . name ( ) ) . map_err ( ParseThresholdError :: ParseK ) ? as usize ;
300+ Threshold :: new ( k, vec ! [ ( ) ; self . n_children ( ) - 1 ] )
274301 . map_err ( ParseThresholdError :: Threshold )
275302 . map_err ( From :: from)
276- . and_then ( |thresh| thresh. translate_by_index ( |i | map_child ( & self . args [ 1 + i ] ) ) )
303+ . and_then ( |thresh| thresh. translate_by_index ( |_ | map_child ( child_iter . next ( ) . unwrap ( ) ) ) )
277304 }
278305
279306 /// Check that a tree has no curly-brace children in it.
0 commit comments