cmail_rpgp/composed/
any.rs1use std::io::{BufRead, Read};
2
3use buffer_redux::BufReader;
4
5use crate::{
6 armor::{self, BlockType, Dearmor},
7 cleartext::CleartextSignedMessage,
8 errors::Result,
9 Deserializable, Message, SignedPublicKey, SignedSecretKey, StandaloneSignature,
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum Any {
15 Cleartext(CleartextSignedMessage),
16 PublicKey(SignedPublicKey),
17 SecretKey(SignedSecretKey),
18 Message(Message),
19 Signature(StandaloneSignature),
20}
21
22impl Any {
23 pub fn from_armor(bytes: impl Read) -> Result<(Self, armor::Headers)> {
25 Self::from_armor_buf(BufReader::new(bytes))
26 }
27
28 pub fn from_string(input: &str) -> Result<(Self, armor::Headers)> {
30 Self::from_armor_buf(input.as_bytes())
31 }
32
33 pub fn from_armor_buf<R: BufRead>(input: R) -> Result<(Self, armor::Headers)> {
35 let dearmor = armor::Dearmor::new(input);
36 let (typ, headers, has_leading_data, rest) = dearmor.read_only_header()?;
37
38 match typ {
39 BlockType::PublicKey => {
41 let dearmor = Dearmor::after_header(typ, headers.clone(), rest);
42 let key = SignedPublicKey::from_bytes(dearmor)?;
43 Ok((Self::PublicKey(key), headers))
44 }
45 BlockType::PrivateKey => {
46 let dearmor = Dearmor::after_header(typ, headers.clone(), rest);
47 let key = SignedSecretKey::from_bytes(dearmor)?;
48 Ok((Self::SecretKey(key), headers))
49 }
50 BlockType::Message => {
51 let dearmor = Dearmor::after_header(typ, headers.clone(), rest);
52 let msg = Message::from_bytes(dearmor)?;
53 Ok((Self::Message(msg), headers))
54 }
55 BlockType::Signature => {
56 let dearmor = Dearmor::after_header(typ, headers.clone(), rest);
57 let sig = StandaloneSignature::from_bytes(dearmor)?;
58 Ok((Self::Signature(sig), headers))
59 }
60 BlockType::CleartextMessage => {
61 ensure!(
62 !has_leading_data,
63 "must not have leading data for a cleartext message"
64 );
65 let (sig, headers) =
66 CleartextSignedMessage::from_armor_after_header(rest, headers)?;
67 Ok((Self::Cleartext(sig), headers))
68 }
69 _ => unimplemented_err!("unsupported block type: {}", typ),
70 }
71 }
72}