@@ -10,7 +10,6 @@ use expression::{self, FromTree, Tree};
1010use std:: sync:: Arc ;
1111use std:: { fmt, str:: FromStr } ;
1212use Segwitv0 ;
13- use MAX_RECURSION_DEPTH ;
1413use { miniscript:: Miniscript , Error , MiniscriptKey } ;
1514
1615#[ derive( Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
@@ -204,105 +203,50 @@ where
204203 }
205204}
206205
207- /// TODO: Refactor to make from_str more generic in `expression.rs`?
208206fn parse_tr < ' a > ( s : & ' a str ) -> Result < Tree < ' a > , Error > {
209207 for ch in s. bytes ( ) {
210208 if ch > 0x7f {
211209 return Err ( Error :: Unprintable ( ch) ) ;
212210 }
213211 }
214212
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,
276220 args : vec ! [ ] ,
277221 } ;
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+ } ) ;
306226 }
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+ } ;
308252}
0 commit comments