|
7 | 7 | //! encoding in Bitcoin script, as well as a datatype. Full details |
8 | 8 | //! are given on the Miniscript website. |
9 | 9 |
|
10 | | -use core::fmt; |
| 10 | +use core::fmt::{self, Write}; |
11 | 11 | use core::str::FromStr; |
12 | 12 |
|
13 | 13 | use bitcoin::hashes::{hash160, Hash}; |
@@ -41,6 +41,25 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> { |
41 | 41 | _ => None, |
42 | 42 | } |
43 | 43 | } |
| 44 | + |
| 45 | + fn conditional_fmt(&self, f: &mut fmt::Formatter, is_debug: bool)-> fmt::Result { |
| 46 | + match *self { |
| 47 | + Terminal::PkK(ref pk) => { |
| 48 | + f.write_str("pk_k(")?; |
| 49 | + conditional_fmt(f, pk, is_debug)?; |
| 50 | + f.write_char(')') |
| 51 | + } |
| 52 | + _ => todo!() |
| 53 | + } |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +fn conditional_fmt<D: fmt::Debug + fmt::Display>(f: &mut fmt::Formatter, data: &D, is_debug: bool) -> fmt::Result { |
| 58 | + if is_debug { |
| 59 | + fmt::Debug::fmt(data, f) |
| 60 | + } else { |
| 61 | + fmt::Display::fmt(data, f) |
| 62 | + } |
44 | 63 | } |
45 | 64 |
|
46 | 65 | impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> { |
@@ -89,154 +108,14 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> { |
89 | 108 | } |
90 | 109 | write!(f, "{:?}", sub) |
91 | 110 | } else { |
92 | | - match *self { |
93 | | - Terminal::PkK(ref pk) => write!(f, "pk_k({:?})", pk), |
94 | | - Terminal::PkH(ref pk) => write!(f, "pk_h({:?})", pk), |
95 | | - Terminal::RawPkH(ref pkh) => write!(f, "expr_raw_pk_h({:?})", pkh), |
96 | | - Terminal::After(t) => write!(f, "after({})", t), |
97 | | - Terminal::Older(t) => write!(f, "older({})", t), |
98 | | - Terminal::Sha256(ref h) => write!(f, "sha256({})", h), |
99 | | - Terminal::Hash256(ref h) => write!(f, "hash256({})", h), |
100 | | - Terminal::Ripemd160(ref h) => write!(f, "ripemd160({})", h), |
101 | | - Terminal::Hash160(ref h) => write!(f, "hash160({})", h), |
102 | | - Terminal::True => f.write_str("1"), |
103 | | - Terminal::False => f.write_str("0"), |
104 | | - Terminal::AndV(ref l, ref r) => write!(f, "and_v({:?},{:?})", l, r), |
105 | | - Terminal::AndB(ref l, ref r) => write!(f, "and_b({:?},{:?})", l, r), |
106 | | - Terminal::AndOr(ref a, ref b, ref c) => { |
107 | | - if c.node == Terminal::False { |
108 | | - write!(f, "and_n({:?},{:?})", a, b) |
109 | | - } else { |
110 | | - write!(f, "andor({:?},{:?},{:?})", a, b, c) |
111 | | - } |
112 | | - } |
113 | | - Terminal::OrB(ref l, ref r) => write!(f, "or_b({:?},{:?})", l, r), |
114 | | - Terminal::OrD(ref l, ref r) => write!(f, "or_d({:?},{:?})", l, r), |
115 | | - Terminal::OrC(ref l, ref r) => write!(f, "or_c({:?},{:?})", l, r), |
116 | | - Terminal::OrI(ref l, ref r) => write!(f, "or_i({:?},{:?})", l, r), |
117 | | - Terminal::Thresh(k, ref subs) => { |
118 | | - write!(f, "thresh({}", k)?; |
119 | | - for s in subs { |
120 | | - write!(f, ",{:?}", s)?; |
121 | | - } |
122 | | - f.write_str(")") |
123 | | - } |
124 | | - Terminal::Multi(k, ref keys) => { |
125 | | - write!(f, "multi({}", k)?; |
126 | | - for k in keys { |
127 | | - write!(f, ",{:?}", k)?; |
128 | | - } |
129 | | - f.write_str(")") |
130 | | - } |
131 | | - Terminal::MultiA(k, ref keys) => { |
132 | | - write!(f, "multi_a({}", k)?; |
133 | | - for k in keys { |
134 | | - write!(f, ",{}", k)?; |
135 | | - } |
136 | | - f.write_str(")") |
137 | | - } |
138 | | - _ => unreachable!(), |
139 | | - } |
| 111 | + self.conditional_fmt(f, true) |
140 | 112 | } |
141 | 113 | } |
142 | 114 | } |
143 | 115 |
|
144 | 116 | impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> { |
145 | 117 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
146 | | - match *self { |
147 | | - Terminal::PkK(ref pk) => write!(f, "pk_k({})", pk), |
148 | | - Terminal::PkH(ref pk) => write!(f, "pk_h({})", pk), |
149 | | - Terminal::RawPkH(ref pkh) => write!(f, "expr_raw_pk_h({})", pkh), |
150 | | - Terminal::After(t) => write!(f, "after({})", t), |
151 | | - Terminal::Older(t) => write!(f, "older({})", t), |
152 | | - Terminal::Sha256(ref h) => write!(f, "sha256({})", h), |
153 | | - Terminal::Hash256(ref h) => write!(f, "hash256({})", h), |
154 | | - Terminal::Ripemd160(ref h) => write!(f, "ripemd160({})", h), |
155 | | - Terminal::Hash160(ref h) => write!(f, "hash160({})", h), |
156 | | - Terminal::True => f.write_str("1"), |
157 | | - Terminal::False => f.write_str("0"), |
158 | | - Terminal::AndV(ref l, ref r) if r.node != Terminal::True => { |
159 | | - write!(f, "and_v({},{})", l, r) |
160 | | - } |
161 | | - Terminal::AndB(ref l, ref r) => write!(f, "and_b({},{})", l, r), |
162 | | - Terminal::AndOr(ref a, ref b, ref c) => { |
163 | | - if c.node == Terminal::False { |
164 | | - write!(f, "and_n({},{})", a, b) |
165 | | - } else { |
166 | | - write!(f, "andor({},{},{})", a, b, c) |
167 | | - } |
168 | | - } |
169 | | - Terminal::OrB(ref l, ref r) => write!(f, "or_b({},{})", l, r), |
170 | | - Terminal::OrD(ref l, ref r) => write!(f, "or_d({},{})", l, r), |
171 | | - Terminal::OrC(ref l, ref r) => write!(f, "or_c({},{})", l, r), |
172 | | - Terminal::OrI(ref l, ref r) |
173 | | - if l.node != Terminal::False && r.node != Terminal::False => |
174 | | - { |
175 | | - write!(f, "or_i({},{})", l, r) |
176 | | - } |
177 | | - Terminal::Thresh(k, ref subs) => { |
178 | | - write!(f, "thresh({}", k)?; |
179 | | - for s in subs { |
180 | | - write!(f, ",{}", s)?; |
181 | | - } |
182 | | - f.write_str(")") |
183 | | - } |
184 | | - Terminal::Multi(k, ref keys) => { |
185 | | - write!(f, "multi({}", k)?; |
186 | | - for k in keys { |
187 | | - write!(f, ",{}", k)?; |
188 | | - } |
189 | | - f.write_str(")") |
190 | | - } |
191 | | - Terminal::MultiA(k, ref keys) => { |
192 | | - write!(f, "multi_a({}", k)?; |
193 | | - for k in keys { |
194 | | - write!(f, ",{}", k)?; |
195 | | - } |
196 | | - f.write_str(")") |
197 | | - } |
198 | | - // wrappers |
199 | | - _ => { |
200 | | - if let Some((ch, sub)) = self.wrap_char() { |
201 | | - if ch == 'c' { |
202 | | - if let Terminal::PkK(ref pk) = sub.node { |
203 | | - // alias: pk(K) = c:pk_k(K) |
204 | | - return write!(f, "pk({})", pk); |
205 | | - } else if let Terminal::RawPkH(ref pkh) = sub.node { |
206 | | - // `RawPkH` is currently unsupported in the descriptor spec |
207 | | - // alias: pkh(K) = c:pk_h(K) |
208 | | - // We temporarily display there using raw_pkh, but these descriptors |
209 | | - // are not defined in the spec yet. These are prefixed with `expr` |
210 | | - // in the descriptor string. |
211 | | - // We do not support parsing these descriptors yet. |
212 | | - return write!(f, "expr_raw_pkh({})", pkh); |
213 | | - } else if let Terminal::PkH(ref pk) = sub.node { |
214 | | - // alias: pkh(K) = c:pk_h(K) |
215 | | - return write!(f, "pkh({})", pk); |
216 | | - } |
217 | | - } |
218 | | - |
219 | | - fmt::Write::write_char(f, ch)?; |
220 | | - match sub.node.wrap_char() { |
221 | | - None => { |
222 | | - fmt::Write::write_char(f, ':')?; |
223 | | - } |
224 | | - // Add a ':' wrapper if there are other wrappers apart from c:pk_k() |
225 | | - // tvc:pk_k() -> tv:pk() |
226 | | - Some(('c', ms)) => match ms.node { |
227 | | - Terminal::PkK(_) | Terminal::PkH(_) | Terminal::RawPkH(_) => { |
228 | | - fmt::Write::write_char(f, ':')? |
229 | | - } |
230 | | - _ => {} |
231 | | - }, |
232 | | - _ => {} |
233 | | - }; |
234 | | - write!(f, "{}", sub) |
235 | | - } else { |
236 | | - unreachable!(); |
237 | | - } |
238 | | - } |
239 | | - } |
| 118 | + self.conditional_fmt(f, false) |
240 | 119 | } |
241 | 120 | } |
242 | 121 |
|
|
0 commit comments