@@ -19,8 +19,8 @@ use crate::policy::Liftable;
19
19
use crate :: prelude:: * ;
20
20
use crate :: util:: { varint_len, witness_size} ;
21
21
use crate :: {
22
- errstr , Error , ForEachKey , MiniscriptKey , Satisfier , ScriptContext , Tap , ToPublicKey ,
23
- TranslateErr , TranslatePk , Translator ,
22
+ Error , ForEachKey , MiniscriptKey , Satisfier , ScriptContext , Tap , ToPublicKey , TranslateErr ,
23
+ TranslatePk , Translator ,
24
24
} ;
25
25
26
26
/// A Taproot Tree representation.
@@ -424,62 +424,60 @@ impl_block_str!(
424
424
Tr <Pk >,
425
425
// Helper function to parse taproot script path
426
426
fn parse_tr_script_spend( tree: & expression:: Tree , ) -> Result <TapTree <Pk >, Error > {
427
- match tree {
428
- expression:: Tree { name, args } if !name. is_empty( ) && args. is_empty( ) => {
429
- let script = Miniscript :: <Pk , Tap >:: from_str( name) ?;
430
- Ok ( TapTree :: Leaf ( Arc :: new( script) ) )
431
- }
432
- expression:: Tree { name, args } if name. is_empty( ) && args. len( ) == 2 => {
433
- let left = Self :: parse_tr_script_spend( & args[ 0 ] ) ?;
434
- let right = Self :: parse_tr_script_spend( & args[ 1 ] ) ?;
435
- Ok ( TapTree :: Tree ( Arc :: new( left) , Arc :: new( right) ) )
436
- }
437
- _ => Err ( Error :: Unexpected (
427
+ if tree. name( ) != "" && tree. n_args( ) == 0 {
428
+ let script = Miniscript :: <Pk , Tap >:: from_str( tree. name( ) ) ?;
429
+ Ok ( TapTree :: Leaf ( Arc :: new( script) ) )
430
+ } else if tree. name( ) == "" && tree. n_args( ) == 2 {
431
+ let left = Self :: parse_tr_script_spend( & tree. args( ) [ 0 ] ) ?;
432
+ let right = Self :: parse_tr_script_spend( & tree. args( ) [ 1 ] ) ?;
433
+ Ok ( TapTree :: Tree ( Arc :: new( left) , Arc :: new( right) ) )
434
+ } else {
435
+ Err ( Error :: Unexpected (
438
436
"unknown format for script spending paths while parsing taproot descriptor"
439
437
. to_string( ) ,
440
- ) ) ,
438
+ ) )
441
439
}
442
440
}
443
441
) ;
444
442
445
443
impl_from_tree ! (
446
444
Tr <Pk >,
447
445
fn from_tree( top: & expression:: Tree ) -> Result <Self , Error > {
448
- if top. name == "tr" {
449
- match top. args . len ( ) {
446
+ if top. name( ) == "tr" {
447
+ match top. n_args ( ) {
450
448
1 => {
451
- let key = & top. args[ 0 ] ;
452
- if !key. args. is_empty( ) {
449
+ let key = & top. args( ) [ 0 ] ;
450
+ if !key. args( ) . is_empty( ) {
453
451
return Err ( Error :: Unexpected ( format!(
454
452
"#{} script associated with `key-path` while parsing taproot descriptor" ,
455
- key. args . len ( )
453
+ key. n_args ( )
456
454
) ) ) ;
457
455
}
458
456
Tr :: new( expression:: terminal( key, Pk :: from_str) ?, None )
459
457
}
460
458
2 => {
461
- let key = & top. args[ 0 ] ;
462
- if !key. args. is_empty( ) {
459
+ let key = & top. args( ) [ 0 ] ;
460
+ if !key. args( ) . is_empty( ) {
463
461
return Err ( Error :: Unexpected ( format!(
464
462
"#{} script associated with `key-path` while parsing taproot descriptor" ,
465
- key. args. len( )
463
+ key. args( ) . len( )
466
464
) ) ) ;
467
465
}
468
- let tree = & top. args[ 1 ] ;
466
+ let tree = & top. args( ) [ 1 ] ;
469
467
let ret = Self :: parse_tr_script_spend( tree) ?;
470
468
Tr :: new( expression:: terminal( key, Pk :: from_str) ?, Some ( ret) )
471
469
}
472
470
_ => Err ( Error :: Unexpected ( format!(
473
471
"{}[#{} args] while parsing taproot descriptor" ,
474
- top. name,
475
- top. args . len ( )
472
+ top. name( ) ,
473
+ top. n_args ( )
476
474
) ) ) ,
477
475
}
478
476
} else {
479
477
Err ( Error :: Unexpected ( format!(
480
478
"{}[#{} args] while parsing taproot descriptor" ,
481
- top. name,
482
- top. args . len ( )
479
+ top. name( ) ,
480
+ top. n_args ( )
483
481
) ) )
484
482
}
485
483
}
@@ -490,7 +488,7 @@ impl_from_str!(
490
488
type Err = Error ; ,
491
489
fn from_str( s: & str ) -> Result <Self , Self :: Err > {
492
490
let desc_str = verify_checksum( s) ?;
493
- let top = parse_tr_tree ( desc_str) ?;
491
+ let top = expression :: Tree :: from_str_tr ( desc_str) ?;
494
492
Self :: from_tree( & top)
495
493
}
496
494
) ;
@@ -517,74 +515,6 @@ impl<Pk: MiniscriptKey> fmt::Display for Tr<Pk> {
517
515
}
518
516
}
519
517
520
- // Helper function to parse string into miniscript tree form
521
- fn parse_tr_tree ( s : & str ) -> Result < expression:: Tree , Error > {
522
- for ch in s. bytes ( ) {
523
- if !ch. is_ascii ( ) {
524
- return Err ( Error :: Unprintable ( ch) ) ;
525
- }
526
- }
527
-
528
- if s. len ( ) > 3 && & s[ ..3 ] == "tr(" && s. as_bytes ( ) [ s. len ( ) - 1 ] == b')' {
529
- let rest = & s[ 3 ..s. len ( ) - 1 ] ;
530
- if !rest. contains ( ',' ) {
531
- let internal_key = expression:: Tree {
532
- name : rest,
533
- args : vec ! [ ] ,
534
- } ;
535
- return Ok ( expression:: Tree {
536
- name : "tr" ,
537
- args : vec ! [ internal_key] ,
538
- } ) ;
539
- }
540
- // use str::split_once() method to refactor this when compiler version bumps up
541
- let ( key, script) = split_once ( rest, ',' )
542
- . ok_or_else ( || Error :: BadDescriptor ( "invalid taproot descriptor" . to_string ( ) ) ) ?;
543
-
544
- let internal_key = expression:: Tree {
545
- name : key,
546
- args : vec ! [ ] ,
547
- } ;
548
- if script. is_empty ( ) {
549
- return Ok ( expression:: Tree {
550
- name : "tr" ,
551
- args : vec ! [ internal_key] ,
552
- } ) ;
553
- }
554
- let ( tree, rest) = expression:: Tree :: from_slice_delim ( script, 1 , '{' ) ?;
555
- if rest. is_empty ( ) {
556
- Ok ( expression:: Tree {
557
- name : "tr" ,
558
- args : vec ! [ internal_key, tree] ,
559
- } )
560
- } else {
561
- Err ( errstr ( rest) )
562
- }
563
- } else {
564
- Err ( Error :: Unexpected ( "invalid taproot descriptor" . to_string ( ) ) )
565
- }
566
- }
567
-
568
- fn split_once ( inp : & str , delim : char ) -> Option < ( & str , & str ) > {
569
- if inp. is_empty ( ) {
570
- None
571
- } else {
572
- let mut found = inp. len ( ) ;
573
- for ( idx, ch) in inp. chars ( ) . enumerate ( ) {
574
- if ch == delim {
575
- found = idx;
576
- break ;
577
- }
578
- }
579
- // No comma or trailing comma found
580
- if found >= inp. len ( ) - 1 {
581
- Some ( ( inp, "" ) )
582
- } else {
583
- Some ( ( & inp[ ..found] , & inp[ found + 1 ..] ) )
584
- }
585
- }
586
- }
587
-
588
518
impl < Pk : MiniscriptKey > Liftable < Pk > for TapTree < Pk > {
589
519
fn lift ( & self ) -> Result < Policy < Pk > , Error > {
590
520
fn lift_helper < Pk : MiniscriptKey > ( s : & TapTree < Pk > ) -> Result < Policy < Pk > , Error > {
0 commit comments