summaryrefslogtreecommitdiffstats
path: root/openpgp/src/keyid.rs
diff options
context:
space:
mode:
authorWiktor Kwapisiewicz <wiktor@metacode.biz>2023-02-10 09:30:22 +0100
committerWiktor Kwapisiewicz <wiktor@metacode.biz>2023-02-10 09:30:22 +0100
commitb43a3408812ef453afc677d243f7aff51715e121 (patch)
tree49f233ba963627be9cd7103bba030732ed6ccf7b /openpgp/src/keyid.rs
parent62cfaf10449deaba06c919e7d50643d503d1dd1d (diff)
openpgp: Optimize writing KeyIDs using Formatter API.
Diffstat (limited to 'openpgp/src/keyid.rs')
-rw-r--r--openpgp/src/keyid.rs63
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(())
}
}