@@ -168,24 +168,22 @@ impl<T: ExtParam> fmt::Debug for AssetExpr<T> {
168
168
}
169
169
}
170
170
171
- impl < T : ExtParam > FromStr for AssetExpr < T > {
172
- type Err = Error ;
173
-
174
- fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
171
+ impl < T : ExtParam > ArgFromStr for AssetExpr < T > {
172
+ fn arg_from_str ( s : & str , parent : & str , pos : usize ) -> Result < Self , Error > {
175
173
let top = expression:: Tree :: from_str ( s) ?;
176
- Self :: from_tree ( & top)
174
+ Self :: from_tree_parent ( & top, parent , pos )
177
175
}
178
176
}
179
177
180
- impl < T : ExtParam > FromTree for AssetExpr < T > {
181
- fn from_tree ( top : & Tree < ' _ > ) -> Result < Self , Error > {
178
+ impl < T : ExtParam > AssetExpr < T > {
179
+ fn from_tree_parent ( top : & Tree < ' _ > , parent : & str , pos : usize ) -> Result < Self , Error > {
182
180
match ( top. name , top. args . len ( ) ) {
183
181
( "curr_inp_asset" , 0 ) => Ok ( AssetExpr :: CurrInputAsset ) ,
184
182
( "inp_asset" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
185
183
. map ( AssetExpr :: Input ) ,
186
184
( "out_asset" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
187
185
. map ( AssetExpr :: Output ) ,
188
- ( asset, 0 ) => Ok ( AssetExpr :: Const ( T :: arg_from_str ( asset, "" , 0 ) ?) ) ,
186
+ ( asset, 0 ) => Ok ( AssetExpr :: Const ( T :: arg_from_str ( asset, parent , pos ) ?) ) ,
189
187
_ => Err ( Error :: Unexpected ( format ! (
190
188
"{}({} args) while parsing Extension" ,
191
189
top. name,
@@ -244,24 +242,22 @@ impl<T: ExtParam> fmt::Debug for ValueExpr<T> {
244
242
}
245
243
}
246
244
247
- impl < T : ExtParam > FromStr for ValueExpr < T > {
248
- type Err = Error ;
249
-
250
- fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
245
+ impl < T : ExtParam > ArgFromStr for ValueExpr < T > {
246
+ fn arg_from_str ( s : & str , parent : & str , pos : usize ) -> Result < Self , Error > {
251
247
let top = expression:: Tree :: from_str ( s) ?;
252
- Self :: from_tree ( & top)
248
+ Self :: from_tree_parent ( & top, parent , pos )
253
249
}
254
250
}
255
251
256
- impl < T : ExtParam > FromTree for ValueExpr < T > {
257
- fn from_tree ( top : & Tree < ' _ > ) -> Result < Self , Error > {
252
+ impl < T : ExtParam > ValueExpr < T > {
253
+ fn from_tree_parent ( top : & Tree < ' _ > , parent : & str , pos : usize ) -> Result < Self , Error > {
258
254
match ( top. name , top. args . len ( ) ) {
259
255
( "curr_inp_value" , 0 ) => Ok ( ValueExpr :: CurrInputValue ) ,
260
256
( "inp_value" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
261
257
. map ( ValueExpr :: Input ) ,
262
258
( "out_value" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
263
259
. map ( ValueExpr :: Output ) ,
264
- ( value, 0 ) => Ok ( ValueExpr :: Const ( T :: arg_from_str ( value, "" , 0 ) ?) ) ,
260
+ ( value, 0 ) => Ok ( ValueExpr :: Const ( T :: arg_from_str ( value, parent , pos ) ?) ) ,
265
261
_ => Err ( Error :: Unexpected ( format ! (
266
262
"{}({} args) while parsing Extension" ,
267
263
top. name,
@@ -320,24 +316,22 @@ impl<T: ExtParam> fmt::Debug for SpkExpr<T> {
320
316
}
321
317
}
322
318
323
- impl < T : ExtParam > FromStr for SpkExpr < T > {
324
- type Err = Error ;
325
-
326
- fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
319
+ impl < T : ExtParam > ArgFromStr for SpkExpr < T > {
320
+ fn arg_from_str ( s : & str , parent : & str , pos : usize ) -> Result < Self , Error > {
327
321
let top = expression:: Tree :: from_str ( s) ?;
328
- Self :: from_tree ( & top)
322
+ Self :: from_tree_parent ( & top, parent , pos )
329
323
}
330
324
}
331
325
332
- impl < T : ExtParam > FromTree for SpkExpr < T > {
333
- fn from_tree ( top : & Tree < ' _ > ) -> Result < Self , Error > {
326
+ impl < T : ExtParam > SpkExpr < T > {
327
+ fn from_tree_parent ( top : & Tree < ' _ > , parent : & str , pos : usize ) -> Result < Self , Error > {
334
328
match ( top. name , top. args . len ( ) ) {
335
329
( "curr_inp_spk" , 0 ) => Ok ( SpkExpr :: CurrInputSpk ) ,
336
330
( "inp_spk" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
337
331
. map ( SpkExpr :: Input ) ,
338
332
( "out_spk" , 1 ) => expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
339
333
. map ( SpkExpr :: Output ) ,
340
- ( asset, 0 ) => Ok ( SpkExpr :: Const ( T :: arg_from_str ( asset, "" , 0 ) ?) ) ,
334
+ ( asset, 0 ) => Ok ( SpkExpr :: Const ( T :: arg_from_str ( asset, parent , pos ) ?) ) ,
341
335
_ => Err ( Error :: Unexpected ( format ! (
342
336
"{}({} args) while parsing Extension" ,
343
337
top. name,
@@ -385,11 +379,27 @@ impl<T: ExtParam> FromStr for CovOps<T> {
385
379
impl < T : ExtParam > FromTree for CovOps < T > {
386
380
fn from_tree ( top : & Tree < ' _ > ) -> Result < Self , Error > {
387
381
match ( top. name , top. args . len ( ) ) {
388
- ( "is_exp_asset" , 1 ) => expression:: unary ( top, CovOps :: IsExpAsset ) ,
389
- ( "is_exp_value" , 1 ) => expression:: unary ( top, CovOps :: IsExpValue ) ,
390
- ( "asset_eq" , 2 ) => expression:: binary ( top, CovOps :: AssetEq ) ,
391
- ( "value_eq" , 2 ) => expression:: binary ( top, CovOps :: ValueEq ) ,
392
- ( "spk_eq" , 2 ) => expression:: binary ( top, CovOps :: SpkEq ) ,
382
+ ( "is_exp_asset" , 1 ) => {
383
+ AssetExpr :: from_tree_parent ( & top. args [ 0 ] , & top. name , 0 ) . map ( CovOps :: IsExpAsset )
384
+ }
385
+ ( "is_exp_value" , 1 ) => {
386
+ ValueExpr :: from_tree_parent ( & top. args [ 0 ] , & top. name , 0 ) . map ( CovOps :: IsExpValue )
387
+ }
388
+ ( "asset_eq" , 2 ) => {
389
+ let l = AssetExpr :: from_tree_parent ( & top. args [ 0 ] , & top. name , 0 ) ?;
390
+ let r = AssetExpr :: from_tree_parent ( & top. args [ 1 ] , & top. name , 1 ) ?;
391
+ Ok ( CovOps :: AssetEq ( l, r) )
392
+ }
393
+ ( "value_eq" , 2 ) => {
394
+ let l = ValueExpr :: from_tree_parent ( & top. args [ 0 ] , & top. name , 0 ) ?;
395
+ let r = ValueExpr :: from_tree_parent ( & top. args [ 1 ] , & top. name , 1 ) ?;
396
+ Ok ( CovOps :: ValueEq ( l, r) )
397
+ }
398
+ ( "spk_eq" , 2 ) => {
399
+ let l = SpkExpr :: from_tree_parent ( & top. args [ 0 ] , & top. name , 0 ) ?;
400
+ let r = SpkExpr :: from_tree_parent ( & top. args [ 1 ] , & top. name , 1 ) ?;
401
+ Ok ( CovOps :: SpkEq ( l, r) )
402
+ }
393
403
( "curr_idx_eq" , 1 ) => {
394
404
expression:: terminal ( & top. args [ 0 ] , expression:: parse_num :: < usize > )
395
405
. map ( CovOps :: CurrIndEq )
@@ -1148,6 +1158,16 @@ mod tests {
1148
1158
_test_parse ( "and_v(v:pk(K),and_v(v:value_eq(ConfVal,ConfVal),and_v(v:spk_eq(V1Spk,V1Spk),curr_idx_eq(1))))" ) ;
1149
1159
}
1150
1160
1161
+ #[ test]
1162
+ fn options_fail_test ( ) {
1163
+ type MsExt = Miniscript < XOnlyPublicKey , Tap , CovOps < CovExtArgs > > ;
1164
+
1165
+ // 33 bytes explicit asset succeeds
1166
+ MsExt :: from_str_insane ( "asset_eq(out_asset(0),0179d51a47e4ac8e32306486dd0926a88678c392f2ed5f213e3ff2ad461c7c25e1)" ) . unwrap ( ) ;
1167
+ // 32 bytes explicit asset without prefix fails
1168
+ MsExt :: from_str_insane ( "asset_eq(out_asset(0),79d51a47e4ac8e32306486dd0926a88678c392f2ed5f213e3ff2ad461c7c25e1)" ) . unwrap_err ( ) ;
1169
+ }
1170
+
1151
1171
#[ rustfmt:: skip]
1152
1172
fn _test_parse ( s : & str ) {
1153
1173
type MsExtStr = Miniscript < String , Tap , CovOps < String > > ;
@@ -1174,5 +1194,7 @@ mod tests {
1174
1194
let ms = ms. translate_ext ( & mut ext_t) . unwrap ( ) ;
1175
1195
// script rtt
1176
1196
assert_eq ! ( ms. encode( ) , MsExt :: parse_insane( & ms. encode( ) ) . unwrap( ) . encode( ) ) ;
1197
+ // String rtt of the translated script
1198
+ assert_eq ! ( ms, MsExt :: from_str_insane( & ms. to_string( ) ) . unwrap( ) )
1177
1199
}
1178
1200
}
0 commit comments