sequoia_openpgp/packet/key/conversions.rs
1//! Conversion functions for `Key` and associated types.
2
3use std::convert::TryFrom;
4
5use crate::Error;
6use crate::cert::prelude::*;
7use crate::packet::prelude::*;
8use crate::packet::key::{
9 KeyParts,
10 KeyRole,
11 PrimaryRole,
12 PublicParts,
13 SubordinateRole,
14 SecretParts,
15 UnspecifiedParts,
16 UnspecifiedRole
17};
18use crate::Result;
19
20macro_rules! convert {
21 ( $x:ident ) => {
22 // XXX: This is ugly, but how can we do better?
23 { // XXX: Appease rustc 1.80.1 which doesn't like annotations on expressions.
24 #[allow(clippy::missing_transmute_annotations)]
25 unsafe { std::mem::transmute($x) }
26 }
27 }
28}
29
30macro_rules! convert_ref {
31 ( $x:ident ) => {
32 // XXX: This is ugly, but how can we do better?
33 #[allow(clippy::missing_transmute_annotations)]
34 unsafe { std::mem::transmute($x) }
35 }
36}
37
38// Make it possible to go from an arbitrary Key<P, R> to an
39// arbitrary Key<P', R'> (or &Key<P, R> to &Key<P', R'>) in a
40// single .into().
41//
42// To allow the programmer to make the intent clearer, also
43// provide explicit conversion function.
44
45// In principle, this is as easy as the following:
46//
47// impl<P, P2, R, R2> From<Key<P, R>> for Key<P2, R2>
48// where P: KeyParts, P2: KeyParts, R: KeyRole, R2: KeyRole
49// {
50// fn from(p: Key<P, R>) -> Self {
51// unimplemented!()
52// }
53// }
54//
55// But that results in:
56//
57// error[E0119]: conflicting implementations of trait `std::convert::From<packet::Key<_, _>>` for type `packet::Key<_, _>`:
58// = note: conflicting implementation in crate `core`:
59// - impl<T> std::convert::From<T> for T;
60//
61// Unfortunately, it's not enough to make one type variable
62// concrete, as the following errors demonstrate:
63//
64// error[E0119]: conflicting implementations of trait `std::convert::From<packet::Key<packet::key::PublicParts, _>>` for type `packet::Key<packet::key::PublicParts, _>`:
65// ...
66// = note: conflicting implementation in crate `core`:
67// - impl<T> std::convert::From<T> for T;
68//
69// impl<P, R, R2> From<Key<P, R>> for Key<PublicParts, R2>
70// where P: KeyParts, R: KeyRole, R2: KeyRole
71// {
72// fn from(p: Key<P, R>) -> Self {
73// unimplemented!()
74// }
75// }
76//
77// error[E0119]: conflicting implementations of trait `std::convert::From<packet::Key<packet::key::PublicParts, _>>` for type `packet::Key<packet::key::PublicParts, _>`:
78// --> openpgp/src/packet/key.rs:186:5
79// ...
80// = note: conflicting implementation in crate `core`:
81// - impl<T> std::convert::From<T> for T;
82// impl<P2, R, R2> From<Key<PublicParts, R>> for Key<P2, R2>
83// where P2: KeyParts, R: KeyRole, R2: KeyRole
84// {
85// fn from(p: Key<PublicParts, R>) -> Self {
86// unimplemented!()
87// }
88// }
89//
90// To solve this, we need at least one generic variable to be
91// concrete on both sides of the `From`.
92
93macro_rules! create_part_conversions {
94 ( $Key:ident<$( $l:lifetime ),*; $( $g:ident ),*>) => {
95 create_part_conversions!($Key<$($l),*; $($g),*> where );
96 };
97 ( $Key:ident<$( $l:lifetime ),*; $( $g:ident ),*> where $( $w:ident: $c:path ),* ) => {
98 // Convert between two KeyParts for a constant KeyRole.
99 // Unfortunately, we can't let the KeyRole vary as otherwise we
100 // get conflicting types when we do the same to convert between
101 // two KeyRoles for a constant KeyParts. :(
102 macro_rules! p {
103 ( <$from_parts:ty> -> <$to_parts:ty> ) => {
104 impl<$($l, )* $($g, )* > From<$Key<$($l, )* $from_parts, $($g, )* >> for $Key<$($l, )* $to_parts, $($g, )* >
105 where $($w: $c ),*
106 {
107 fn from(p: $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
108 convert!(p)
109 }
110 }
111
112 impl<$($l, )* $($g, )* > From<&$($l)* $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* $Key<$($l, )* $to_parts, $($g, )* >
113 where $($w: $c ),*
114 {
115 fn from(p: &$($l)* $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
116 convert_ref!(p)
117 }
118 }
119
120 impl<$($l, )* $($g, )* > From<&$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* mut $Key<$($l, )* $to_parts, $($g, )* >
121 where $($w: $c ),*
122 {
123 fn from(p: &$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
124 convert_ref!(p)
125 }
126 }
127 }
128 }
129
130 // Likewise, but using TryFrom.
131 macro_rules! p_try {
132 ( <$from_parts:ty> -> <$to_parts:ty>) => {
133 impl<$($l, )* $($g, )* > TryFrom<$Key<$($l, )* $from_parts, $($g, )* >> for $Key<$($l, )* $to_parts, $($g, )* >
134 where $($w: $c ),*
135 {
136 type Error = anyhow::Error;
137 fn try_from(p: $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
138 p.parts_into_secret()
139 }
140 }
141
142 impl<$($l, )* $($g, )* > TryFrom<&$($l)* $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* $Key<$($l, )* $to_parts, $($g, )* >
143 where $($w: $c ),*
144 {
145 type Error = anyhow::Error;
146 fn try_from(p: &$($l)* $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
147 if p.has_secret() {
148 Ok(convert_ref!(p))
149 } else {
150 Err(Error::InvalidArgument("No secret key".into())
151 .into())
152 }
153 }
154 }
155
156 impl<$($l, )* $($g, )* > TryFrom<&$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* mut $Key<$($l, )* $to_parts, $($g, )* >
157 where $($w: $c ),*
158 {
159 type Error = anyhow::Error;
160 fn try_from(p: &$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
161 if p.has_secret() {
162 Ok(convert_ref!(p))
163 } else {
164 Err(Error::InvalidArgument("No secret key".into())
165 .into())
166 }
167 }
168 }
169 }
170 }
171
172
173 p_try!(<PublicParts> -> <SecretParts>);
174 p!(<PublicParts> -> <UnspecifiedParts>);
175
176 p!(<SecretParts> -> <PublicParts>);
177 p!(<SecretParts> -> <UnspecifiedParts>);
178
179 p!(<UnspecifiedParts> -> <PublicParts>);
180 p_try!(<UnspecifiedParts> -> <SecretParts>);
181
182
183 impl<$($l, )* P, $($g, )*> $Key<$($l, )* P, $($g, )*> where P: KeyParts, $($w: $c ),*
184 {
185 /// Changes the key's parts tag to `PublicParts`.
186 pub fn parts_into_public(self) -> $Key<$($l, )* PublicParts, $($g, )*> {
187 // Ideally, we'd use self.into() to do the actually
188 // conversion. But, because P is not concrete, we get the
189 // following error:
190 //
191 // error[E0277]: the trait bound `packet::Key<packet::key::PublicParts, R>: std::convert::From<packet::Key<P, R>>` is not satisfied
192 // --> openpgp/src/packet/key.rs:401:18
193 // |
194 // 401 | self.into()
195 // | ^^^^ the trait `std::convert::From<packet::Key<P, R>>` is not implemented for `packet::Key<packet::key::PublicParts, R>`
196 // |
197 // = help: consider adding a `where packet::Key<packet::key::PublicParts, R>: std::convert::From<packet::Key<P, R>>` bound
198 // = note: required because of the requirements on the impl of `std::convert::Into<packet::Key<packet::key::PublicParts, R>>` for `packet::Key<P, R>`
199 //
200 // But we can't implement implement `From<Key<P, R>>` for
201 // `Key<PublicParts, R>`, because that conflicts with a
202 // standard conversion! (See the comment for the `p`
203 // macro above.)
204 //
205 // Adding the trait bound is annoying, because then we'd
206 // have to add it everywhere that we use into.
207 convert!(self)
208 }
209
210 /// Changes the key's parts tag to `PublicParts`.
211 pub fn parts_as_public(&$($l)* self) -> &$($l)* $Key<$($l, )* PublicParts, $($g, )*> {
212 convert_ref!(self)
213 }
214
215 /// Changes the key's parts tag to `PublicParts`.
216 pub fn parts_as_public_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* PublicParts, $($g, )*> {
217 convert_ref!(self)
218 }
219
220 /// Changes the key's parts tag to `SecretParts`.
221 pub fn parts_into_secret(self) -> Result<$Key<$($l, )* SecretParts, $($g, )*>> {
222 if self.has_secret() {
223 Ok(convert!(self))
224 } else {
225 Err(Error::InvalidArgument("No secret key".into()).into())
226 }
227 }
228
229 /// Changes the key's parts tag to `SecretParts`.
230 pub fn parts_as_secret(&$($l)* self) -> Result<&$($l)* $Key<$($l, )* SecretParts, $($g, )*>>
231 {
232 if self.has_secret() {
233 Ok(convert_ref!(self))
234 } else {
235 Err(Error::InvalidArgument("No secret key".into()).into())
236 }
237 }
238
239 /// Changes the key's parts tag to `SecretParts`.
240 pub fn parts_as_secret_mut(&$($l)* mut self) -> Result<&$($l)* mut $Key<$($l, )* SecretParts, $($g, )*>>
241 {
242 if self.has_secret() {
243 Ok(convert_ref!(self))
244 } else {
245 Err(Error::InvalidArgument("No secret key".into()).into())
246 }
247 }
248
249 /// Changes the key's parts tag to `UnspecifiedParts`.
250 pub fn parts_into_unspecified(self) -> $Key<$($l, )* UnspecifiedParts, $($g, )*> {
251 convert!(self)
252 }
253
254 /// Changes the key's parts tag to `UnspecifiedParts`.
255 pub fn parts_as_unspecified(&$($l)* self) -> &$($l)* $Key<$($l, )* UnspecifiedParts, $($g, )*> {
256 convert_ref!(self)
257 }
258
259 /// Changes the key's parts tag to `UnspecifiedParts`.
260 pub fn parts_as_unspecified_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* UnspecifiedParts, $($g, )*> {
261 convert_ref!(self)
262 }
263 }
264 }
265}
266
267macro_rules! create_role_conversions {
268 ( $Key:ident<$( $l:lifetime ),*> ) => {
269 // Convert between two KeyRoles for a constant KeyParts. See
270 // the comment for the p macro above.
271 macro_rules! r {
272 ( <$from_role:ty> -> <$to_role:ty>) => {
273 impl<$($l, )* P> From<$Key<$($l, )* P, $from_role>> for $Key<$($l, )* P, $to_role>
274 where P: KeyParts
275 {
276 fn from(p: $Key<$($l, )* P, $from_role>) -> Self {
277 let mut k: Self = convert!(p);
278 k.set_role(<$to_role>::role());
279 k
280 }
281 }
282
283 impl<$($l, )* P> From<&$($l)* $Key<$($l, )* P, $from_role>> for &$($l)* $Key<$($l, )* P, $to_role>
284 where P: KeyParts
285 {
286 fn from(p: &$($l)* $Key<$($l, )* P, $from_role>) -> Self {
287 convert_ref!(p)
288 }
289 }
290
291 impl<$($l, )* P> From<&$($l)* mut $Key<$($l, )* P, $from_role>> for &$($l)* mut $Key<$($l, )* P, $to_role>
292 where P: KeyParts
293 {
294 fn from(p: &$($l)* mut $Key<$($l, )* P, $from_role>) -> Self {
295 convert_ref!(p)
296 }
297 }
298 }
299 }
300
301 r!(<PrimaryRole> -> <SubordinateRole>);
302 r!(<PrimaryRole> -> <UnspecifiedRole>);
303
304 r!(<SubordinateRole> -> <PrimaryRole>);
305 r!(<SubordinateRole> -> <UnspecifiedRole>);
306
307 r!(<UnspecifiedRole> -> <PrimaryRole>);
308 r!(<UnspecifiedRole> -> <SubordinateRole>);
309 }
310}
311
312macro_rules! create_conversions {
313 ( $Key:ident ) => {
314 create_conversions!(@ $Key);
315 };
316 ( $Key:ident < $( $l:lifetime ),* > ) => {
317 create_conversions!(@ $Key $( $l ),*);
318 };
319 ( @ $Key:ident $( $l:lifetime ),* ) => {
320 create_part_conversions!($Key<$($l ),* ; R> where R: KeyRole);
321 create_role_conversions!($Key<$($l ),* >);
322
323 // We now handle converting both the part and the role at the same
324 // time.
325
326 macro_rules! f {
327 ( <$from_parts:ty, $from_role:ty> -> <$to_parts:ty, $to_role:ty> ) => {
328 impl<$($l ),*> From<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* $to_parts, $to_role>
329 {
330 fn from(p: $Key<$($l, )* $from_parts, $from_role>) -> Self {
331 let mut k: Self = convert!(p);
332 k.set_role(<$to_role>::role());
333 k
334 }
335 }
336
337 impl<$($l ),*> From<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* $to_parts, $to_role>
338 {
339 fn from(p: &$($l)* $Key<$from_parts, $from_role>) -> Self {
340 convert_ref!(p)
341 }
342 }
343
344 impl<$($l ),*> From<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* $to_parts, $to_role>
345 {
346 fn from(p: &$($l)* mut $Key<$from_parts, $from_role>) -> Self {
347 convert_ref!(p)
348 }
349 }
350 }
351 }
352
353 macro_rules! f_try {
354 ( <$from_parts:ty, $from_role:ty> -> <SecretParts, $to_role:ty> ) => {
355 impl<$($l ),*> TryFrom<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* SecretParts, $to_role>
356 {
357 type Error = anyhow::Error;
358 fn try_from(p: $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
359 // First, just change the role.
360 let mut k: $Key<$($l, )* $from_parts, $to_role> = p.into();
361 k.set_role(<$to_role>::role());
362 // Now change the parts.
363 k.try_into()
364 }
365 }
366
367 impl<$($l ),*> TryFrom<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* SecretParts, $to_role>
368 {
369 type Error = anyhow::Error;
370 fn try_from(p: &$($l)* $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
371 // First, just change the role.
372 let k: &$($l)* $Key<$($l, )* $from_parts, $to_role> = p.into();
373 // Now change the parts.
374 k.try_into()
375 }
376 }
377
378 impl<$($l ),*> TryFrom<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* SecretParts, $to_role>
379 {
380 type Error = anyhow::Error;
381 fn try_from(p: &$($l)* mut $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
382 // First, just change the role.
383 let k: &$($l)* mut $Key<$($l, )* $from_parts, $to_role> = p.into();
384 // Now change the parts.
385 k.try_into()
386 }
387 }
388 }
389 }
390
391 // The calls that are comment out are the calls for the
392 // combinations where either the KeyParts or the KeyRole does not
393 // change.
394
395 //f!(<PublicParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
396 //f!(<PublicParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
397 //f!(<PublicParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
398 //f!(<PublicParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
399 f_try!(<PublicParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
400 f_try!(<PublicParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
401 //f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
402 f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
403 f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
404
405 //f!(<PublicParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
406 //f!(<PublicParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
407 //f!(<PublicParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
408 f_try!(<PublicParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
409 //f!(<PublicParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
410 f_try!(<PublicParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
411 f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
412 //f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
413 f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
414
415 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
416 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
417 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
418 f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
419 f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
420 //f!(<PublicParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
421 f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
422 f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
423 //f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
424
425 //f!(<SecretParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
426 f!(<SecretParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
427 f!(<SecretParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
428 //f!(<SecretParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
429 //f!(<SecretParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
430 //f!(<SecretParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
431 //f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
432 f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
433 f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
434
435 f!(<SecretParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
436 //f!(<SecretParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
437 f!(<SecretParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
438 //f!(<SecretParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
439 //f!(<SecretParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
440 //f!(<SecretParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
441 f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
442 //f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
443 f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
444
445 f!(<SecretParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
446 f!(<SecretParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
447 //f!(<SecretParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
448 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
449 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
450 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
451 f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
452 f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
453 //f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
454
455 //f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
456 f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
457 f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
458 //f!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
459 f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
460 f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
461 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
462 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
463 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
464
465 f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
466 //f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
467 f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
468 f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
469 //f!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
470 f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
471 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
472 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
473 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
474
475 f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
476 f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
477 //f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
478 f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
479 f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
480 //f!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
481 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
482 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
483 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
484
485
486 impl<$($l, )* P, R> $Key<$($l, )* P, R> where P: KeyParts, R: KeyRole
487 {
488 /// Changes the key's role tag to `PrimaryRole`.
489 pub fn role_into_primary(self) -> $Key<$($l, )* P, PrimaryRole> {
490 let mut k: $Key<$($l, )* P, PrimaryRole> = convert!(self);
491 k.set_role(PrimaryRole::role());
492 k
493 }
494
495 /// Changes the key's role tag to `PrimaryRole`.
496 pub fn role_as_primary(&$($l)* self) -> &$($l)* $Key<$($l, )* P, PrimaryRole> {
497 convert_ref!(self)
498 }
499
500 /// Changes the key's role tag to `PrimaryRole`.
501 pub fn role_as_primary_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, PrimaryRole> {
502 convert_ref!(self)
503 }
504
505 /// Changes the key's role tag to `SubordinateRole`.
506 pub fn role_into_subordinate(self) -> $Key<$($l, )* P, SubordinateRole>
507 {
508 let mut k: $Key<$($l, )* P, SubordinateRole> = convert!(self);
509 k.set_role(SubordinateRole::role());
510 k
511 }
512
513 /// Changes the key's role tag to `SubordinateRole`.
514 pub fn role_as_subordinate(&$($l)* self) -> &$($l)* $Key<$($l, )* P, SubordinateRole>
515 {
516 convert_ref!(self)
517 }
518
519 /// Changes the key's role tag to `SubordinateRole`.
520 pub fn role_as_subordinate_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, SubordinateRole>
521 {
522 convert_ref!(self)
523 }
524
525 /// Changes the key's role tag to `UnspecifiedRole`.
526 pub fn role_into_unspecified(self) -> $Key<$($l, )* P, UnspecifiedRole>
527 {
528 let mut k: $Key<$($l, )* P, UnspecifiedRole> = convert!(self);
529 k.set_role(UnspecifiedRole::role());
530 k
531 }
532
533 /// Changes the key's role tag to `UnspecifiedRole`.
534 pub fn role_as_unspecified(&$($l)* self) -> &$($l)* $Key<$($l, )* P, UnspecifiedRole>
535 {
536 convert_ref!(self)
537 }
538
539 /// Changes the key's role tag to `UnspecifiedRole`.
540 pub fn role_as_unspecified_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, UnspecifiedRole>
541 {
542 convert_ref!(self)
543 }
544 }
545 }
546}
547
548create_conversions!(Key);
549create_conversions!(Key4);
550create_conversions!(Key6);
551create_conversions!(KeyBundle);
552
553// A hack, since the type has to be an ident, which means that we
554// can't use <>.
555type KeyComponentAmalgamation<'a, P, R> = ComponentAmalgamation<'a, Key<P, R>>;
556create_conversions!(KeyComponentAmalgamation<'a>);
557
558create_part_conversions!(PrimaryKeyAmalgamation<'a;>);
559create_part_conversions!(SubordinateKeyAmalgamation<'a;>);
560create_part_conversions!(ErasedKeyAmalgamation<'a;>);
561create_part_conversions!(ValidPrimaryKeyAmalgamation<'a;>);
562create_part_conversions!(ValidSubordinateKeyAmalgamation<'a;>);
563create_part_conversions!(ValidErasedKeyAmalgamation<'a;>);