diff options
author | Neal H. Walfield <neal@pep.foundation> | 2020-12-22 12:46:52 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2020-12-22 12:46:52 +0100 |
commit | 455923648b254e9ea74bd05d1af46ab50a6a07eb (patch) | |
tree | e80a8f26e4aeb25896439832da79e4bc9ee5bc7e /openpgp/src/keyhandle.rs | |
parent | c74db5da27a2942aee2a65ba119a110495f8299d (diff) |
openpgp: Implement str::FromStr for KeyHandle.
- We implement str::FromStr for Fingerprint and KeyID. Also
implement it for KeyHandle.
Diffstat (limited to 'openpgp/src/keyhandle.rs')
-rw-r--r-- | openpgp/src/keyhandle.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/openpgp/src/keyhandle.rs b/openpgp/src/keyhandle.rs index e3d56820..70e4dbda 100644 --- a/openpgp/src/keyhandle.rs +++ b/openpgp/src/keyhandle.rs @@ -205,6 +205,25 @@ impl PartialEq for KeyHandle { } } +impl std::str::FromStr for KeyHandle { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { + let bytes = &crate::fmt::hex::decode_pretty(s)?[..]; + match Fingerprint::from_bytes(bytes) { + fpr @ Fingerprint::Invalid(_) => { + match KeyID::from_bytes(bytes) { + // If it can't be parsed as either a Fingerprint or a + // KeyID, return Fingerprint::Invalid. + KeyID::Invalid(_) => Ok(fpr.into()), + kid => Ok(kid.into()), + } + } + fpr => Ok(fpr.into()), + } + } +} + impl KeyHandle { /// Returns the raw identifier as a byte slice. pub fn as_bytes(&self) -> &[u8] { @@ -316,4 +335,31 @@ mod tests { let handle = KeyHandle::KeyID(KeyID::Invalid(Box::new([10, 2]))); assert_eq!(format!("{:x}", handle), "0a02"); } + + #[test] + fn parse() -> Result<()> { + let handle: KeyHandle = + "0123 4567 89AB CDEF 0123 4567 89AB CDEF 0123 4567".parse()?; + assert_match!(&KeyHandle::Fingerprint(Fingerprint::V4(_)) = &handle); + assert_eq!(handle.as_bytes(), + [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67]); + + let handle: KeyHandle = "89AB CDEF 0123 4567".parse()?; + assert_match!(&KeyHandle::KeyID(KeyID::V4(_)) = &handle); + assert_eq!(handle.as_bytes(), + [0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67]); + + // Invalid handles are parsed as invalid Fingerprints, not + // invalid KeyIDs. + let handle: KeyHandle = "4567 89AB CDEF 0123 4567".parse()?; + assert_match!(&KeyHandle::Fingerprint(Fingerprint::Invalid(_)) = &handle); + assert_eq!(handle.as_bytes(), + [0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67]); + + let handle: Result<KeyHandle> = "INVALID CHARACTERS".parse(); + assert!(handle.is_err()); + + Ok(()) + } } |