sequoia_openpgp/packet/
any.rs1use crate::packet::{
4 Packet,
5 Unknown,
6 Signature,
7 OnePassSig,
8 Key,
9 key,
10 Marker,
11 Trust,
12 UserID,
13 UserAttribute,
14 Literal,
15 CompressedData,
16 PKESK,
17 SKESK,
18 SEIP,
19 MDC,
20 Padding,
21};
22
23pub trait Any<T>: crate::seal::Sealed {
35 fn downcast(self) -> std::result::Result<T, Packet>;
46
47 fn downcast_ref(&self) -> Option<&T>;
58
59 fn downcast_mut(&mut self) -> Option<&mut T>;
70}
71
72macro_rules! impl_downcast_for {
73 ($typ: tt) => {
74 impl_downcast_for!($typ => $typ);
75 };
76 ($($typ: tt)|* => $subtyp: ty) => {
77 #[allow(deprecated)]
78 impl Any<$subtyp> for Packet {
79 fn downcast(self) -> std::result::Result<$subtyp, Packet> {
80 match self {
81 $(Packet::$typ(v) => Ok(v.into()),)*
82 p => Err(p),
83 }
84 }
85
86 fn downcast_ref(&self) -> Option<&$subtyp> {
87 match self {
88 $(Packet::$typ(v) => Some(v.into()),)*
89 _ => None,
90 }
91 }
92
93 fn downcast_mut(&mut self) -> Option<&mut $subtyp> {
94 match self {
95 $(Packet::$typ(v) => Some(v.into()),)*
96 _ => None,
97 }
98 }
99 }
100 };
101}
102
103macro_rules! impl_downcasts {
104 ($($typ:ident, )*) => {
105 $(impl_downcast_for!($typ);)*
106
107 #[allow(unused, deprecated)]
112 fn check_exhaustion(p: Packet) {
113 match p {
114 $(Packet::$typ(_) => (),)*
115 Packet::PublicKey(_) => (),
117 Packet::PublicSubkey(_) => (),
118 Packet::SecretKey(_) => (),
119 Packet::SecretSubkey(_) => (),
120 }
121 }
122 }
123}
124
125impl_downcasts!(
126 Unknown,
127 Signature,
128 OnePassSig,
129 Marker,
130 Trust,
131 UserID,
132 UserAttribute,
133 Literal,
134 CompressedData,
135 PKESK,
136 SKESK,
137 SEIP,
138 MDC,
139 Padding,
140);
141
142impl_downcast_for!(PublicKey | SecretKey
147 => Key<key::PublicParts, key::PrimaryRole>);
148impl_downcast_for!(PublicSubkey | SecretSubkey
149 => Key<key::PublicParts, key::SubordinateRole>);
150impl_downcast_for!(PublicKey | PublicSubkey | SecretKey | SecretSubkey
151 => Key<key::PublicParts, key::UnspecifiedRole>);
152
153impl_downcast_for!(SecretKey
155 => Key<key::SecretParts, key::PrimaryRole>);
156impl_downcast_for!(SecretSubkey
157 => Key<key::SecretParts, key::SubordinateRole>);
158impl_downcast_for!(SecretKey | SecretSubkey
159 => Key<key::SecretParts, key::UnspecifiedRole>);
160
161impl_downcast_for!(PublicKey | SecretKey
163 => Key<key::UnspecifiedParts, key::PrimaryRole>);
164impl_downcast_for!(PublicSubkey | SecretSubkey
165 => Key<key::UnspecifiedParts, key::SubordinateRole>);
166impl_downcast_for!(PublicKey | PublicSubkey | SecretKey | SecretSubkey
167 => Key<key::UnspecifiedParts, key::UnspecifiedRole>);
168
169#[cfg(test)]
170mod test {
171 use super::*;
172
173 #[test]
174 fn downcast() {
175 let p: Packet = Marker::default().into();
176 let mut p = Any::<UserID>::downcast(p).unwrap_err();
177 let r: Option<&UserID> = p.downcast_ref();
178 assert!(r.is_none());
179 let r: Option<&mut UserID> = p.downcast_mut();
180 assert!(r.is_none());
181 let _: &Marker = p.downcast_ref().unwrap();
182 let _: &mut Marker = p.downcast_mut().unwrap();
183 let _: Marker = p.downcast().unwrap();
184 }
185}