diff options
author | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2023-02-10 09:30:22 +0100 |
---|---|---|
committer | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2023-02-10 09:30:22 +0100 |
commit | b43a3408812ef453afc677d243f7aff51715e121 (patch) | |
tree | 49f233ba963627be9cd7103bba030732ed6ccf7b /openpgp/src/keyid.rs | |
parent | 62cfaf10449deaba06c919e7d50643d503d1dd1d (diff) |
openpgp: Optimize writing KeyIDs using Formatter API.
Diffstat (limited to 'openpgp/src/keyid.rs')
-rw-r--r-- | openpgp/src/keyid.rs | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/openpgp/src/keyid.rs b/openpgp/src/keyid.rs index e93c603d..1c83c63b 100644 --- a/openpgp/src/keyid.rs +++ b/openpgp/src/keyid.rs @@ -83,15 +83,13 @@ impl fmt::Debug for KeyID { impl fmt::UpperHex for KeyID { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&self.convert_to_string(false)) + self.write_to_fmt(f, true) } } impl fmt::LowerHex for KeyID { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut hex = self.convert_to_string(false); - hex.make_ascii_lowercase(); - f.write_str(&hex) + self.write_to_fmt(f, false) } } @@ -306,7 +304,18 @@ impl KeyID { /// # Ok(()) } /// ``` pub fn to_hex(&self) -> String { - format!("{:X}", self) + use std::fmt::Write; + + let raw_len = self.as_bytes().len(); + let mut output = String::with_capacity( + // Each byte results in two hex characters. + raw_len * 2); + + // We write to String that never fails but the Write API + // returns Results. + write!(output, "{:X}", self).unwrap(); + + output } /// Converts this `KeyID` to its hexadecimal representation with @@ -331,7 +340,21 @@ impl KeyID { /// # Ok(()) } /// ``` pub fn to_spaced_hex(&self) -> String { - self.convert_to_string(true) + use std::fmt::Write; + + let raw_len = self.as_bytes().len(); + let mut output = String::with_capacity( + // Each byte results in two hex characters. + raw_len * 2 + + + // Every 2 bytes of output, we insert a space. + raw_len / 2); + + // We write to String that never fails but the Write API + // returns Results. + write!(output, "{:#X}", self).unwrap(); + + output } /// Parses the hexadecimal representation of an OpenPGP `KeyID`. @@ -355,7 +378,12 @@ impl KeyID { } /// Common code for the above functions. - fn convert_to_string(&self, pretty: bool) -> String { + fn write_to_fmt(&self, f: &mut fmt::Formatter, upper_case: bool) -> fmt::Result { + use std::fmt::Write; + + let a_letter = if upper_case { b'A' } else { b'a' }; + let pretty = f.alternate(); + let raw = match self { KeyID::V4(ref fp) => &fp[..], KeyID::Invalid(ref fp) => &fp[..], @@ -368,37 +396,28 @@ impl KeyID { // Since we have no idea how to format an invalid Key ID, just // format it like a V4 fingerprint and hope for the best. - let mut output = Vec::with_capacity( - // Each byte results in to hex characters. - raw.len() * 2 - + if pretty { - // Every 2 bytes of output, we insert a space. - raw.len() / 2 - } else { 0 }); - for (i, b) in raw.iter().enumerate() { if pretty && i > 0 && i % 2 == 0 { - output.push(b' '); + f.write_char(' ')?; } let top = b >> 4; let bottom = b & 0xFu8; if top < 10u8 { - output.push(b'0' + top) + f.write_char((b'0' + top) as char)?; } else { - output.push(b'A' + (top - 10u8)) + f.write_char((a_letter + (top - 10u8)) as char)?; } if bottom < 10u8 { - output.push(b'0' + bottom) + f.write_char((b'0' + bottom) as char)?; } else { - output.push(b'A' + (bottom - 10u8)) + f.write_char((a_letter + (bottom - 10u8)) as char)?; } } - // We know the content is valid UTF-8. - String::from_utf8(output).unwrap() + Ok(()) } } |