Skip to content

Commit c36d295

Browse files
committed
Merge rust-bitcoin#4624: impl LowerHex, UpperHex, Octal, and Binary for ChildNumber
7dc66e3 impl LowerHex, UpperHex, Octal, and Binary for ChildNumber (vicjuma) Pull request description: apoelstra Each trait forwards formatting to the inner u32 index. For Hardened variants, a suffix is appended based on whether alternate formatting is used per the discussion. See discussion: rust-bitcoin#4620 (comment) ACKs for top commit: tcharding: ACK 7dc66e3 apoelstra: ACK 7dc66e3; successfully ran local tests Tree-SHA512: 49e4acc82198d3a2c807bf8977413dd260a7081b83e8ad2c2b97d8fcaf85b78a54552098a5fe3020c78fe7b908d90a3bab86be20f330d3de569b5eba69e23348
2 parents f034367 + 7dc66e3 commit c36d295

File tree

1 file changed

+96
-8
lines changed

1 file changed

+96
-8
lines changed

bitcoin/src/bip32.rs

Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,29 @@ impl ChildNumber {
193193
ChildNumber::Hardened { index: idx } => ChildNumber::from_hardened_idx(idx + 1),
194194
}
195195
}
196+
197+
/// Formats the child number using the provided formatting function.
198+
///
199+
/// For hardened child numbers appends a `'` or `hardened_alt_suffix`
200+
/// depending on the formatter.
201+
fn format_with<F>(
202+
&self,
203+
f: &mut fmt::Formatter,
204+
format_fn: F,
205+
hardened_alt_suffix: &str,
206+
) -> fmt::Result
207+
where
208+
F: Fn(&u32, &mut fmt::Formatter) -> fmt::Result,
209+
{
210+
match *self {
211+
ChildNumber::Hardened { index } => {
212+
format_fn(&index, f)?;
213+
let alt = f.alternate();
214+
f.write_str(if alt { hardened_alt_suffix } else { "'" })
215+
}
216+
ChildNumber::Normal { index } => format_fn(&index, f),
217+
}
218+
}
196219
}
197220

198221
impl From<u32> for ChildNumber {
@@ -216,14 +239,31 @@ impl From<ChildNumber> for u32 {
216239

217240
impl fmt::Display for ChildNumber {
218241
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
219-
match *self {
220-
ChildNumber::Hardened { index } => {
221-
fmt::Display::fmt(&index, f)?;
222-
let alt = f.alternate();
223-
f.write_str(if alt { "h" } else { "'" })
224-
}
225-
ChildNumber::Normal { index } => fmt::Display::fmt(&index, f),
226-
}
242+
self.format_with(f, fmt::Display::fmt, "h")
243+
}
244+
}
245+
246+
impl fmt::LowerHex for ChildNumber {
247+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248+
self.format_with(f, fmt::LowerHex::fmt, "h")
249+
}
250+
}
251+
252+
impl fmt::UpperHex for ChildNumber {
253+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254+
self.format_with(f, fmt::UpperHex::fmt, "H")
255+
}
256+
}
257+
258+
impl fmt::Octal for ChildNumber {
259+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260+
self.format_with(f, fmt::Octal::fmt, "h")
261+
}
262+
}
263+
264+
impl fmt::Binary for ChildNumber {
265+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
266+
self.format_with(f, fmt::Binary::fmt, "h")
227267
}
228268
}
229269

@@ -1123,6 +1163,54 @@ mod tests {
11231163
assert_eq!(format!("{:#}", path), "84h/0h/0h/0/0");
11241164
}
11251165

1166+
#[test]
1167+
fn test_lowerhex_formatting() {
1168+
let normal = Normal { index: 42 };
1169+
let hardened = Hardened { index: 42 };
1170+
1171+
assert_eq!(format!("{:x}", normal), "2a");
1172+
assert_eq!(format!("{:#x}", normal), "0x2a");
1173+
1174+
assert_eq!(format!("{:x}", hardened), "2a'");
1175+
assert_eq!(format!("{:#x}", hardened), "0x2ah");
1176+
}
1177+
1178+
#[test]
1179+
fn test_upperhex_formatting() {
1180+
let normal = Normal { index: 42 };
1181+
let hardened = Hardened { index: 42 };
1182+
1183+
assert_eq!(format!("{:X}", normal), "2A");
1184+
assert_eq!(format!("{:#X}", normal), "0x2A");
1185+
1186+
assert_eq!(format!("{:X}", hardened), "2A'");
1187+
assert_eq!(format!("{:#X}", hardened), "0x2AH");
1188+
}
1189+
1190+
#[test]
1191+
fn test_octal_formatting() {
1192+
let normal = Normal { index: 42 };
1193+
let hardened = Hardened { index: 42 };
1194+
1195+
assert_eq!(format!("{:o}", normal), "52");
1196+
assert_eq!(format!("{:#o}", normal), "0o52");
1197+
1198+
assert_eq!(format!("{:o}", hardened), "52'");
1199+
assert_eq!(format!("{:#o}", hardened), "0o52h");
1200+
}
1201+
1202+
#[test]
1203+
fn test_binary_formatting() {
1204+
let normal = Normal { index: 42 };
1205+
let hardened = Hardened { index: 42 };
1206+
1207+
assert_eq!(format!("{:b}", normal), "101010");
1208+
assert_eq!(format!("{:#b}", normal), "0b101010");
1209+
1210+
assert_eq!(format!("{:b}", hardened), "101010'");
1211+
assert_eq!(format!("{:#b}", hardened), "0b101010h");
1212+
}
1213+
11261214
#[test]
11271215
fn parse_derivation_path_out_of_range() {
11281216
let invalid_path = "2147483648";

0 commit comments

Comments
 (0)