@@ -10,7 +10,6 @@ use expression::{self, FromTree, Tree};
10
10
use std:: sync:: Arc ;
11
11
use std:: { fmt, str:: FromStr } ;
12
12
use Segwitv0 ;
13
- use MAX_RECURSION_DEPTH ;
14
13
use { miniscript:: Miniscript , Error , MiniscriptKey } ;
15
14
16
15
#[ derive( Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
@@ -204,105 +203,50 @@ where
204
203
}
205
204
}
206
205
207
- /// TODO: Refactor to make from_str more generic in `expression.rs`?
208
206
fn parse_tr < ' a > ( s : & ' a str ) -> Result < Tree < ' a > , Error > {
209
207
for ch in s. bytes ( ) {
210
208
if ch > 0x7f {
211
209
return Err ( Error :: Unprintable ( ch) ) ;
212
210
}
213
211
}
214
212
215
- let ( top, rem) = parse_tr_helper ( s, 0 ) ?;
216
- if rem. is_empty ( ) {
217
- Ok ( top)
218
- } else {
219
- Err ( errstr ( rem) )
220
- }
221
- }
222
-
223
- /// Helper function to parse Taproot Descriptor into key_path and TapTree
224
- fn parse_tr_helper < ' a > ( mut sl : & ' a str , depth : u32 ) -> Result < ( Tree < ' a > , & ' a str ) , Error > {
225
- if depth >= MAX_RECURSION_DEPTH {
226
- return Err ( Error :: MaxRecursiveDepthExceeded ) ;
227
- }
228
-
229
- enum Found {
230
- Nothing ,
231
- Lparen ( usize ) ,
232
- Comma ( usize ) ,
233
- Rparen ( usize ) ,
234
- }
235
-
236
- let mut found = Found :: Nothing ;
237
- for ( n, ch) in sl. char_indices ( ) {
238
- match ch {
239
- '(' => {
240
- found = Found :: Lparen ( n) ;
241
- break ;
242
- }
243
- ',' => {
244
- found = Found :: Comma ( n) ;
245
- break ;
246
- }
247
- ')' => {
248
- found = Found :: Rparen ( n) ;
249
- break ;
250
- }
251
- _ => { }
252
- }
253
- }
254
-
255
- match found {
256
- // String-ending terminal
257
- Found :: Nothing => Ok ( (
258
- Tree {
259
- name : & sl[ ..] ,
260
- args : vec ! [ ] ,
261
- } ,
262
- "" ,
263
- ) ) ,
264
- // Terminal
265
- Found :: Comma ( n) | Found :: Rparen ( n) => Ok ( (
266
- Tree {
267
- name : & sl[ ..n] ,
268
- args : vec ! [ ] ,
269
- } ,
270
- & sl[ n..] ,
271
- ) ) ,
272
- // Function call
273
- Found :: Lparen ( n) => {
274
- let mut ret = Tree {
275
- name : & sl[ ..n] ,
213
+ // let (top, rem) = parse_tr_helper(s, 0)?;
214
+ // parsing a taproot descriptor
215
+ return if s. len ( ) > 3 && & s[ ..3 ] == "tr(" && s. as_bytes ( ) [ s. len ( ) - 1 ] == b')' {
216
+ let rest = & s[ 3 ..s. len ( ) - 1 ] ;
217
+ if !rest. contains ( ',' ) {
218
+ let key_path = Tree {
219
+ name : rest,
276
220
args : vec ! [ ] ,
277
221
} ;
278
-
279
- sl = & sl[ n + 1 ..] ;
280
- let mut prev_sl: & str = "" ;
281
- let mut prev_arg: Tree ;
282
- loop {
283
- if prev_sl. contains ( "{" ) {
284
- let ( arg, new_sl) = expression:: Tree :: from_slice_helper_curly ( sl, depth + 1 ) ?;
285
- prev_arg = arg;
286
- prev_sl = new_sl;
287
- } else {
288
- let ( arg, new_sl) = parse_tr_helper ( sl, depth + 1 ) ?;
289
- prev_arg = arg;
290
- prev_sl = new_sl;
291
- }
292
- ret. args . push ( prev_arg) ;
293
-
294
- if prev_sl. is_empty ( ) {
295
- return Err ( Error :: ExpectedChar ( ')' ) ) ;
296
- }
297
-
298
- sl = & prev_sl[ 1 ..] ;
299
- match prev_sl. as_bytes ( ) [ 0 ] {
300
- b',' => { }
301
- b')' => break ,
302
- _ => return Err ( Error :: ExpectedChar ( ')' ) ) ,
303
- }
304
- }
305
- Ok ( ( ret, sl) )
222
+ return Ok ( Tree {
223
+ name : "tr" ,
224
+ args : vec ! [ key_path] ,
225
+ } ) ;
306
226
}
307
- }
227
+ let ( key, script) = rest
228
+ . split_once ( ',' )
229
+ . ok_or_else ( || Error :: BadDescriptor ( "invalid taproot descriptor" . to_string ( ) ) ) ?;
230
+ let key_path = Tree {
231
+ name : key,
232
+ args : vec ! [ ] ,
233
+ } ;
234
+ if script. is_empty ( ) {
235
+ return Ok ( Tree {
236
+ name : "tr" ,
237
+ args : vec ! [ key_path] ,
238
+ } ) ;
239
+ }
240
+ let ( script_path, rest) = expression:: Tree :: from_slice_helper_curly ( script, 0 ) ?;
241
+ if rest. is_empty ( ) {
242
+ Ok ( Tree {
243
+ name : "tr" ,
244
+ args : vec ! [ key_path, script_path] ,
245
+ } )
246
+ } else {
247
+ Err ( errstr ( rest) )
248
+ }
249
+ } else {
250
+ Err ( Error :: Unexpected ( "invalid taproot descriptor" . to_string ( ) ) )
251
+ } ;
308
252
}
0 commit comments