@@ -42,197 +42,89 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
42
42
_ => None ,
43
43
}
44
44
}
45
- }
46
45
47
- impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Debug for Terminal < Pk , Ctx > {
48
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
49
- f. write_str ( "[" ) ?;
50
- if let Ok ( type_map) = types:: Type :: type_check ( self ) {
51
- f. write_str ( match type_map. corr . base {
52
- types:: Base :: B => "B" ,
53
- types:: Base :: K => "K" ,
54
- types:: Base :: V => "V" ,
55
- types:: Base :: W => "W" ,
56
- } ) ?;
57
- fmt:: Write :: write_char ( f, '/' ) ?;
58
- f. write_str ( match type_map. corr . input {
59
- types:: Input :: Zero => "z" ,
60
- types:: Input :: One => "o" ,
61
- types:: Input :: OneNonZero => "on" ,
62
- types:: Input :: Any => "" ,
63
- types:: Input :: AnyNonZero => "n" ,
64
- } ) ?;
65
- if type_map. corr . dissatisfiable {
66
- fmt:: Write :: write_char ( f, 'd' ) ?;
67
- }
68
- if type_map. corr . unit {
69
- fmt:: Write :: write_char ( f, 'u' ) ?;
70
- }
71
- f. write_str ( match type_map. mall . dissat {
72
- types:: Dissat :: None => "f" ,
73
- types:: Dissat :: Unique => "e" ,
74
- types:: Dissat :: Unknown => "" ,
75
- } ) ?;
76
- if type_map. mall . safe {
77
- fmt:: Write :: write_char ( f, 's' ) ?;
78
- }
79
- if type_map. mall . non_malleable {
80
- fmt:: Write :: write_char ( f, 'm' ) ?;
81
- }
82
- } else {
83
- f. write_str ( "TYPECHECK FAILED" ) ?;
84
- }
85
- f. write_str ( "]" ) ?;
86
- if let Some ( ( ch, sub) ) = self . wrap_char ( ) {
87
- fmt:: Write :: write_char ( f, ch) ?;
88
- if sub. node . wrap_char ( ) . is_none ( ) {
89
- fmt:: Write :: write_char ( f, ':' ) ?;
90
- }
91
- write ! ( f, "{:?}" , sub)
92
- } else {
93
- match * self {
94
- Terminal :: PkK ( ref pk) => write ! ( f, "pk_k({:?})" , pk) ,
95
- Terminal :: PkH ( ref pk) => write ! ( f, "pk_h({:?})" , pk) ,
96
- Terminal :: RawPkH ( ref pkh) => write ! ( f, "expr_raw_pk_h({:?})" , pkh) ,
97
- Terminal :: After ( t) => write ! ( f, "after({})" , t) ,
98
- Terminal :: Older ( t) => write ! ( f, "older({})" , t) ,
99
- Terminal :: Sha256 ( ref h) => write ! ( f, "sha256({})" , h) ,
100
- Terminal :: Hash256 ( ref h) => write ! ( f, "hash256({})" , h) ,
101
- Terminal :: Ripemd160 ( ref h) => write ! ( f, "ripemd160({})" , h) ,
102
- Terminal :: Hash160 ( ref h) => write ! ( f, "hash160({})" , h) ,
103
- Terminal :: True => f. write_str ( "1" ) ,
104
- Terminal :: False => f. write_str ( "0" ) ,
105
- Terminal :: AndV ( ref l, ref r) => write ! ( f, "and_v({:?},{:?})" , l, r) ,
106
- Terminal :: AndB ( ref l, ref r) => write ! ( f, "and_b({:?},{:?})" , l, r) ,
107
- Terminal :: AndOr ( ref a, ref b, ref c) => {
108
- if c. node == Terminal :: False {
109
- write ! ( f, "and_n({:?},{:?})" , a, b)
110
- } else {
111
- write ! ( f, "andor({:?},{:?},{:?})" , a, b, c)
112
- }
113
- }
114
- Terminal :: OrB ( ref l, ref r) => write ! ( f, "or_b({:?},{:?})" , l, r) ,
115
- Terminal :: OrD ( ref l, ref r) => write ! ( f, "or_d({:?},{:?})" , l, r) ,
116
- Terminal :: OrC ( ref l, ref r) => write ! ( f, "or_c({:?},{:?})" , l, r) ,
117
- Terminal :: OrI ( ref l, ref r) => write ! ( f, "or_i({:?},{:?})" , l, r) ,
118
- Terminal :: Thresh ( k, ref subs) => {
119
- write ! ( f, "thresh({}" , k) ?;
120
- for s in subs {
121
- write ! ( f, ",{:?}" , s) ?;
122
- }
123
- f. write_str ( ")" )
124
- }
125
- Terminal :: Multi ( k, ref keys) => {
126
- write ! ( f, "multi({}" , k) ?;
127
- for k in keys {
128
- write ! ( f, ",{:?}" , k) ?;
129
- }
130
- f. write_str ( ")" )
131
- }
132
- Terminal :: MultiA ( k, ref keys) => {
133
- write ! ( f, "multi_a({}" , k) ?;
134
- for k in keys {
135
- write ! ( f, ",{}" , k) ?;
136
- }
137
- f. write_str ( ")" )
138
- }
139
- _ => unreachable ! ( ) ,
140
- }
141
- }
142
- }
143
- }
144
-
145
- impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Display for Terminal < Pk , Ctx > {
146
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
46
+ fn conditional_fmt ( & self , f : & mut fmt:: Formatter , is_debug : bool ) -> fmt:: Result {
147
47
match * self {
148
- Terminal :: PkK ( ref pk) => write ! ( f, "pk_k({}) " , pk) ,
149
- Terminal :: PkH ( ref pk) => write ! ( f, "pk_h({}) " , pk) ,
150
- Terminal :: RawPkH ( ref pkh) => write ! ( f, "expr_raw_pk_h({}) " , pkh) ,
151
- Terminal :: After ( t) => write ! ( f, "after({}) " , t) ,
152
- Terminal :: Older ( t) => write ! ( f, "older({}) " , t) ,
153
- Terminal :: Sha256 ( ref h) => write ! ( f, "sha256({}) " , h) ,
154
- Terminal :: Hash256 ( ref h) => write ! ( f, "hash256({}) " , h) ,
155
- Terminal :: Ripemd160 ( ref h) => write ! ( f, "ripemd160({}) " , h) ,
156
- Terminal :: Hash160 ( ref h) => write ! ( f, "hash160({}) " , h) ,
48
+ Terminal :: PkK ( ref pk) => fmt_1 ( f, "pk_k(" , pk, is_debug ) ,
49
+ Terminal :: PkH ( ref pk) => fmt_1 ( f, "pk_h(" , pk, is_debug ) ,
50
+ Terminal :: RawPkH ( ref pkh) => fmt_1 ( f, "expr_raw_pk_h(" , pkh, is_debug ) ,
51
+ Terminal :: After ( ref t) => fmt_1 ( f, "after(" , t, is_debug ) ,
52
+ Terminal :: Older ( ref t) => fmt_1 ( f, "older(" , t, is_debug ) ,
53
+ Terminal :: Sha256 ( ref h) => fmt_1 ( f, "sha256(" , h, is_debug ) ,
54
+ Terminal :: Hash256 ( ref h) => fmt_1 ( f, "hash256(" , h, is_debug ) ,
55
+ Terminal :: Ripemd160 ( ref h) => fmt_1 ( f, "ripemd160(" , h, is_debug ) ,
56
+ Terminal :: Hash160 ( ref h) => fmt_1 ( f, "hash160(" , h, is_debug ) ,
157
57
Terminal :: True => f. write_str ( "1" ) ,
158
58
Terminal :: False => f. write_str ( "0" ) ,
159
59
Terminal :: AndV ( ref l, ref r) if r. node != Terminal :: True => {
160
- write ! ( f, "and_v({},{}) " , l, r)
60
+ fmt_2 ( f, "and_v(" , l, r, is_debug )
161
61
}
162
- Terminal :: AndB ( ref l, ref r) => write ! ( f, "and_b({},{}) " , l, r) ,
62
+ Terminal :: AndB ( ref l, ref r) => fmt_2 ( f, "and_b(" , l, r, is_debug ) ,
163
63
Terminal :: AndOr ( ref a, ref b, ref c) => {
164
64
if c. node == Terminal :: False {
165
- write ! ( f, "and_n({},{}) " , a, b)
65
+ fmt_2 ( f, "and_b( " , a, b, is_debug )
166
66
} else {
167
- write ! ( f, "andor({},{},{})" , a, b, c)
67
+ f. write_str ( "andor(" ) ?;
68
+ conditional_fmt ( f, a, is_debug) ?;
69
+ f. write_str ( "," ) ?;
70
+ conditional_fmt ( f, b, is_debug) ?;
71
+ f. write_str ( "," ) ?;
72
+ conditional_fmt ( f, c, is_debug) ?;
73
+ f. write_str ( ")" )
168
74
}
169
75
}
170
- Terminal :: OrB ( ref l, ref r) => write ! ( f, "or_b({},{}) " , l, r) ,
171
- Terminal :: OrD ( ref l, ref r) => write ! ( f, "or_d({},{}) " , l, r) ,
172
- Terminal :: OrC ( ref l, ref r) => write ! ( f, "or_c({},{}) " , l, r) ,
76
+ Terminal :: OrB ( ref l, ref r) => fmt_2 ( f, "or_b(" , l, r, is_debug ) ,
77
+ Terminal :: OrD ( ref l, ref r) => fmt_2 ( f, "or_d(" , l, r, is_debug ) ,
78
+ Terminal :: OrC ( ref l, ref r) => fmt_2 ( f, "or_c(" , l, r, is_debug ) ,
173
79
Terminal :: OrI ( ref l, ref r)
174
80
if l. node != Terminal :: False && r. node != Terminal :: False =>
175
81
{
176
- write ! ( f, "or_i({},{})" , l, r)
177
- }
178
- Terminal :: Thresh ( k, ref subs) => {
179
- write ! ( f, "thresh({}" , k) ?;
180
- for s in subs {
181
- write ! ( f, ",{}" , s) ?;
182
- }
183
- f. write_str ( ")" )
184
- }
185
- Terminal :: Multi ( k, ref keys) => {
186
- write ! ( f, "multi({}" , k) ?;
187
- for k in keys {
188
- write ! ( f, ",{}" , k) ?;
189
- }
190
- f. write_str ( ")" )
191
- }
192
- Terminal :: MultiA ( k, ref keys) => {
193
- write ! ( f, "multi_a({}" , k) ?;
194
- for k in keys {
195
- write ! ( f, ",{}" , k) ?;
196
- }
197
- f. write_str ( ")" )
82
+ fmt_2 ( f, "or_i(" , l, r, is_debug)
198
83
}
84
+ Terminal :: Thresh ( k, ref subs) => fmt_n ( f, "thresh(" , k, subs, is_debug) ,
85
+ Terminal :: Multi ( k, ref keys) => fmt_n ( f, "multi(" , k, keys, is_debug) ,
86
+ Terminal :: MultiA ( k, ref keys) => fmt_n ( f, "multi_a(" , k, keys, is_debug) ,
199
87
// wrappers
200
88
_ => {
201
89
if let Some ( ( ch, sub) ) = self . wrap_char ( ) {
202
90
if ch == 'c' {
203
91
if let Terminal :: PkK ( ref pk) = sub. node {
204
92
// alias: pk(K) = c:pk_k(K)
205
- return write ! ( f, "pk({}) " , pk) ;
93
+ return fmt_1 ( f, "pk(" , pk, is_debug ) ;
206
94
} else if let Terminal :: RawPkH ( ref pkh) = sub. node {
207
95
// `RawPkH` is currently unsupported in the descriptor spec
208
96
// alias: pkh(K) = c:pk_h(K)
209
97
// We temporarily display there using raw_pkh, but these descriptors
210
98
// are not defined in the spec yet. These are prefixed with `expr`
211
99
// in the descriptor string.
212
100
// We do not support parsing these descriptors yet.
213
- return write ! ( f, "expr_raw_pkh({}) " , pkh) ;
101
+ return fmt_1 ( f, "expr_raw_pkh(" , pkh, is_debug ) ;
214
102
} else if let Terminal :: PkH ( ref pk) = sub. node {
215
103
// alias: pkh(K) = c:pk_h(K)
216
- return write ! ( f, "pkh({}) " , pk) ;
104
+ return fmt_1 ( f, "pkh(" , pk, is_debug ) ;
217
105
}
218
106
}
219
107
220
108
fmt:: Write :: write_char ( f, ch) ?;
221
109
match sub. node . wrap_char ( ) {
222
110
None => {
223
- fmt :: Write :: write_char ( f , ':' ) ?;
111
+ f . write_str ( ":" ) ?;
224
112
}
225
113
// Add a ':' wrapper if there are other wrappers apart from c:pk_k()
226
114
// tvc:pk_k() -> tv:pk()
227
115
Some ( ( 'c' , ms) ) => match ms. node {
228
116
Terminal :: PkK ( _) | Terminal :: PkH ( _) | Terminal :: RawPkH ( _) => {
229
- fmt :: Write :: write_char ( f , ':' ) ?
117
+ f . write_str ( ":" ) ? ;
230
118
}
231
119
_ => { }
232
120
} ,
233
121
_ => { }
234
122
} ;
235
- write ! ( f, "{}" , sub)
123
+ if is_debug {
124
+ write ! ( f, "{:?}" , sub)
125
+ } else {
126
+ write ! ( f, "{}" , sub)
127
+ }
236
128
} else {
237
129
unreachable ! ( ) ;
238
130
}
@@ -241,6 +133,109 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
241
133
}
242
134
}
243
135
136
+ fn fmt_1 < D : fmt:: Debug + fmt:: Display > (
137
+ f : & mut fmt:: Formatter ,
138
+ name : & str ,
139
+ a : & D ,
140
+ is_debug : bool ,
141
+ ) -> fmt:: Result {
142
+ f. write_str ( & name) ?;
143
+ conditional_fmt ( f, a, is_debug) ?;
144
+ f. write_str ( ")" )
145
+ }
146
+ fn fmt_2 < D : fmt:: Debug + fmt:: Display > (
147
+ f : & mut fmt:: Formatter ,
148
+ name : & str ,
149
+ a : & D ,
150
+ b : & D ,
151
+ is_debug : bool ,
152
+ ) -> fmt:: Result {
153
+ f. write_str ( & name) ?;
154
+ conditional_fmt ( f, a, is_debug) ?;
155
+ f. write_str ( "," ) ?;
156
+ conditional_fmt ( f, b, is_debug) ?;
157
+ f. write_str ( ")" )
158
+ }
159
+ fn fmt_n < D : fmt:: Debug + fmt:: Display > (
160
+ f : & mut fmt:: Formatter ,
161
+ name : & str ,
162
+ first : usize ,
163
+ list : & [ D ] ,
164
+ is_debug : bool ,
165
+ ) -> fmt:: Result {
166
+ f. write_str ( & name) ?;
167
+ write ! ( f, "{}" , first) ?;
168
+ for el in list {
169
+ f. write_str ( "," ) ?;
170
+ conditional_fmt ( f, el, is_debug) ?;
171
+ }
172
+ f. write_str ( ")" )
173
+ }
174
+ fn conditional_fmt < D : fmt:: Debug + fmt:: Display > (
175
+ f : & mut fmt:: Formatter ,
176
+ data : & D ,
177
+ is_debug : bool ,
178
+ ) -> fmt:: Result {
179
+ if is_debug {
180
+ fmt:: Debug :: fmt ( data, f)
181
+ } else {
182
+ fmt:: Display :: fmt ( data, f)
183
+ }
184
+ }
185
+
186
+ impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Debug for Terminal < Pk , Ctx > {
187
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
188
+ fn fmt_type_map ( f : & mut fmt:: Formatter < ' _ > , type_map : types:: Type ) -> fmt:: Result {
189
+ f. write_str ( match type_map. corr . base {
190
+ types:: Base :: B => "B" ,
191
+ types:: Base :: K => "K" ,
192
+ types:: Base :: V => "V" ,
193
+ types:: Base :: W => "W" ,
194
+ } ) ?;
195
+ f. write_str ( "/" ) ?;
196
+ f. write_str ( match type_map. corr . input {
197
+ types:: Input :: Zero => "z" ,
198
+ types:: Input :: One => "o" ,
199
+ types:: Input :: OneNonZero => "on" ,
200
+ types:: Input :: Any => "" ,
201
+ types:: Input :: AnyNonZero => "n" ,
202
+ } ) ?;
203
+ if type_map. corr . dissatisfiable {
204
+ f. write_str ( "d" ) ?;
205
+ }
206
+ if type_map. corr . unit {
207
+ f. write_str ( "u" ) ?;
208
+ }
209
+ f. write_str ( match type_map. mall . dissat {
210
+ types:: Dissat :: None => "f" ,
211
+ types:: Dissat :: Unique => "e" ,
212
+ types:: Dissat :: Unknown => "" ,
213
+ } ) ?;
214
+ if type_map. mall . safe {
215
+ f. write_str ( "s" ) ?;
216
+ }
217
+ if type_map. mall . non_malleable {
218
+ f. write_str ( "m" ) ?;
219
+ }
220
+ Ok ( ( ) )
221
+ }
222
+
223
+ f. write_str ( "[" ) ?;
224
+ if let Ok ( type_map) = types:: Type :: type_check ( self ) {
225
+ fmt_type_map ( f, type_map) ?;
226
+ } else {
227
+ f. write_str ( "TYPECHECK FAILED" ) ?;
228
+ }
229
+ f. write_str ( "]" ) ?;
230
+
231
+ self . conditional_fmt ( f, true )
232
+ }
233
+ }
234
+
235
+ impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Display for Terminal < Pk , Ctx > {
236
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result { self . conditional_fmt ( f, false ) }
237
+ }
238
+
244
239
impl < Pk : FromStrKey , Ctx : ScriptContext > crate :: expression:: FromTree for Arc < Terminal < Pk , Ctx > > {
245
240
fn from_tree ( top : & expression:: Tree ) -> Result < Arc < Terminal < Pk , Ctx > > , Error > {
246
241
Ok ( Arc :: new ( expression:: FromTree :: from_tree ( top) ?) )
0 commit comments