@@ -37,110 +37,39 @@ pub trait FromTree: Sized {
3737 fn from_tree ( top : & Tree ) -> Result < Self , Error > ;
3838}
3939
40- impl < ' a > Tree < ' a > {
41- /// Parse an expression with round brackets
42- pub fn from_slice ( sl : & ' a str ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
43- // Parsing TapTree or just miniscript
44- Self :: from_slice_helper_round ( sl, 0u32 )
45- }
46-
47- fn from_slice_helper_round ( mut sl : & ' a str , depth : u32 ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
48- if depth >= MAX_RECURSION_DEPTH {
49- return Err ( Error :: MaxRecursiveDepthExceeded ) ;
50- }
51- enum Found {
52- Nothing ,
53- Lparen ( usize ) ,
54- Comma ( usize ) ,
55- Rparen ( usize ) ,
56- }
40+ enum Found {
41+ Nothing ,
42+ LBracket ( usize ) , // Either a left ( or {
43+ Comma ( usize ) ,
44+ RBracket ( usize ) , // Either a right ) or }
45+ }
5746
58- let mut found = Found :: Nothing ;
47+ fn next_expr ( sl : & str , delim : char ) -> Found {
48+ let mut found = Found :: Nothing ;
49+ if delim == '(' {
5950 for ( n, ch) in sl. char_indices ( ) {
6051 match ch {
6152 '(' => {
62- found = Found :: Lparen ( n) ;
53+ found = Found :: LBracket ( n) ;
6354 break ;
6455 }
6556 ',' => {
6657 found = Found :: Comma ( n) ;
6758 break ;
6859 }
6960 ')' => {
70- found = Found :: Rparen ( n) ;
61+ found = Found :: RBracket ( n) ;
7162 break ;
7263 }
7364 _ => { }
7465 }
7566 }
76-
77- match found {
78- // String-ending terminal
79- Found :: Nothing => Ok ( (
80- Tree {
81- name : & sl[ ..] ,
82- args : vec ! [ ] ,
83- } ,
84- "" ,
85- ) ) ,
86- // Terminal
87- Found :: Comma ( n) | Found :: Rparen ( n) => Ok ( (
88- Tree {
89- name : & sl[ ..n] ,
90- args : vec ! [ ] ,
91- } ,
92- & sl[ n..] ,
93- ) ) ,
94- // Function call
95- Found :: Lparen ( n) => {
96- let mut ret = Tree {
97- name : & sl[ ..n] ,
98- args : vec ! [ ] ,
99- } ;
100-
101- sl = & sl[ n + 1 ..] ;
102- loop {
103- let ( arg, new_sl) = Tree :: from_slice_helper_round ( sl, depth + 1 ) ?;
104- ret. args . push ( arg) ;
105-
106- if new_sl. is_empty ( ) {
107- return Err ( Error :: ExpectedChar ( ')' ) ) ;
108- }
109-
110- sl = & new_sl[ 1 ..] ;
111- match new_sl. as_bytes ( ) [ 0 ] {
112- b',' => { }
113- b')' => break ,
114- _ => return Err ( Error :: ExpectedChar ( ',' ) ) ,
115- }
116- }
117- Ok ( ( ret, sl) )
118- }
119- }
120- }
121-
122- // Helper function to parse expressions with curly braces
123- pub ( crate ) fn from_slice_helper_curly (
124- mut sl : & ' a str ,
125- depth : u32 ,
126- ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
127- // contain the context of brackets
128- if depth >= MAX_RECURSION_DEPTH {
129- return Err ( Error :: MaxRecursiveDepthExceeded ) ;
130- }
131- enum Found {
132- Nothing ,
133- Lbrace ( usize ) ,
134- Comma ( usize ) ,
135- Rbrace ( usize ) ,
136- }
137-
138- let mut found = Found :: Nothing ;
67+ } else if delim == '{' {
13968 let mut new_count = 0 ;
14069 for ( n, ch) in sl. char_indices ( ) {
14170 match ch {
14271 '{' => {
143- found = Found :: Lbrace ( n) ;
72+ found = Found :: LBracket ( n) ;
14473 break ;
14574 }
14675 '(' => {
@@ -156,14 +85,44 @@ impl<'a> Tree<'a> {
15685 new_count -= 1 ;
15786 }
15887 '}' => {
159- found = Found :: Rbrace ( n) ;
88+ found = Found :: RBracket ( n) ;
16089 break ;
16190 }
16291 _ => { }
16392 }
16493 }
94+ } else {
95+ unreachable ! ( "Internal: delimiters in parsing must be '(' or '{'" ) ;
96+ }
97+ found
98+ }
99+
100+ // Get the corresponding delim
101+ fn closing_delim ( delim : char ) -> char {
102+ match delim {
103+ '(' => ')' ,
104+ '{' => '}' ,
105+ _ => unreachable ! ( "Unknown delimiter" ) ,
106+ }
107+ }
165108
166- match found {
109+ impl < ' a > Tree < ' a > {
110+ /// Parse an expression with round brackets
111+ pub fn from_slice ( sl : & ' a str ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
112+ // Parsing TapTree or just miniscript
113+ Self :: from_slice_delim ( sl, 0u32 , '(' )
114+ }
115+
116+ pub ( crate ) fn from_slice_delim (
117+ mut sl : & ' a str ,
118+ depth : u32 ,
119+ delim : char ,
120+ ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
121+ if depth >= MAX_RECURSION_DEPTH {
122+ return Err ( Error :: MaxRecursiveDepthExceeded ) ;
123+ }
124+
125+ match next_expr ( sl, delim) {
167126 // String-ending terminal
168127 Found :: Nothing => Ok ( (
169128 Tree {
@@ -173,34 +132,39 @@ impl<'a> Tree<'a> {
173132 "" ,
174133 ) ) ,
175134 // Terminal
176- Found :: Comma ( n) | Found :: Rbrace ( n) => Ok ( (
135+ Found :: Comma ( n) | Found :: RBracket ( n) => Ok ( (
177136 Tree {
178137 name : & sl[ ..n] ,
179138 args : vec ! [ ] ,
180139 } ,
181140 & sl[ n..] ,
182141 ) ) ,
183142 // Function call
184- Found :: Lbrace ( n) => {
143+ Found :: LBracket ( n) => {
185144 let mut ret = Tree {
186- name : & sl[ ..n] , // Would be empty for left and right assignments
145+ name : & sl[ ..n] ,
187146 args : vec ! [ ] ,
188147 } ;
189148
190149 sl = & sl[ n + 1 ..] ;
191150 loop {
192- let ( arg, new_sl) = Tree :: from_slice_helper_curly ( sl, depth + 1 ) ?;
151+ let ( arg, new_sl) = Tree :: from_slice_delim ( sl, depth + 1 , delim ) ?;
193152 ret. args . push ( arg) ;
194153
195154 if new_sl. is_empty ( ) {
196- return Err ( Error :: ExpectedChar ( '}' ) ) ;
155+ return Err ( Error :: ExpectedChar ( closing_delim ( delim ) ) ) ;
197156 }
198157
199158 sl = & new_sl[ 1 ..] ;
200159 match new_sl. as_bytes ( ) [ 0 ] {
201160 b',' => { }
202- b'}' => break ,
203- _ => return Err ( Error :: ExpectedChar ( ',' ) ) ,
161+ last_byte => {
162+ if last_byte == closing_delim ( delim) as u8 {
163+ break ;
164+ } else {
165+ return Err ( Error :: ExpectedChar ( closing_delim ( delim) ) ) ;
166+ }
167+ }
204168 }
205169 }
206170 Ok ( ( ret, sl) )
0 commit comments