summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-12-22 12:46:52 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-12-22 12:46:52 +0100
commit455923648b254e9ea74bd05d1af46ab50a6a07eb (patch)
treee80a8f26e4aeb25896439832da79e4bc9ee5bc7e
parentc74db5da27a2942aee2a65ba119a110495f8299d (diff)
openpgp: Implement str::FromStr for KeyHandle.
- We implement str::FromStr for Fingerprint and KeyID. Also implement it for KeyHandle.
-rw-r--r--openpgp/src/keyhandle.rs46
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(())
+ }
}