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<$( $l:lifetime ),*> ) => {
314 create_part_conversions!($Key<$($l ),* ; R> where R: KeyRole);
315 create_role_conversions!($Key<$($l ),* >);
316
317 // We now handle converting both the part and the role at the same
318 // time.
319
320 macro_rules! f {
321 ( <$from_parts:ty, $from_role:ty> -> <$to_parts:ty, $to_role:ty> ) => {
322 impl<$($l ),*> From<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* $to_parts, $to_role>
323 {
324 fn from(p: $Key<$($l, )* $from_parts, $from_role>) -> Self {
325 let mut k: Self = convert!(p);
326 k.set_role(<$to_role>::role());
327 k
328 }
329 }
330
331 impl<$($l ),*> From<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* $to_parts, $to_role>
332 {
333 fn from(p: &$($l)* $Key<$from_parts, $from_role>) -> Self {
334 convert_ref!(p)
335 }
336 }
337
338 impl<$($l ),*> From<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* $to_parts, $to_role>
339 {
340 fn from(p: &$($l)* mut $Key<$from_parts, $from_role>) -> Self {
341 convert_ref!(p)
342 }
343 }
344 }
345 }
346
347 macro_rules! f_try {
348 ( <$from_parts:ty, $from_role:ty> -> <SecretParts, $to_role:ty> ) => {
349 impl<$($l ),*> TryFrom<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* SecretParts, $to_role>
350 {
351 type Error = anyhow::Error;
352 fn try_from(p: $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
353 // First, just change the role.
354 let mut k: $Key<$($l, )* $from_parts, $to_role> = p.into();
355 k.set_role(<$to_role>::role());
356 // Now change the parts.
357 k.try_into()
358 }
359 }
360
361 impl<$($l ),*> TryFrom<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* SecretParts, $to_role>
362 {
363 type Error = anyhow::Error;
364 fn try_from(p: &$($l)* $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
365 // First, just change the role.
366 let k: &$($l)* $Key<$($l, )* $from_parts, $to_role> = p.into();
367 // Now change the parts.
368 k.try_into()
369 }
370 }
371
372 impl<$($l ),*> TryFrom<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* SecretParts, $to_role>
373 {
374 type Error = anyhow::Error;
375 fn try_from(p: &$($l)* mut $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
376 // First, just change the role.
377 let k: &$($l)* mut $Key<$($l, )* $from_parts, $to_role> = p.into();
378 // Now change the parts.
379 k.try_into()
380 }
381 }
382 }
383 }
384
385 // The calls that are comment out are the calls for the
386 // combinations where either the KeyParts or the KeyRole does not
387 // change.
388
389 //f!(<PublicParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
390 //f!(<PublicParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
391 //f!(<PublicParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
392 //f!(<PublicParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
393 f_try!(<PublicParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
394 f_try!(<PublicParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
395 //f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
396 f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
397 f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
398
399 //f!(<PublicParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
400 //f!(<PublicParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
401 //f!(<PublicParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
402 f_try!(<PublicParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
403 //f!(<PublicParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
404 f_try!(<PublicParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
405 f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
406 //f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
407 f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
408
409 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
410 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
411 //f!(<PublicParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
412 f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
413 f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
414 //f!(<PublicParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
415 f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
416 f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
417 //f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
418
419 //f!(<SecretParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
420 f!(<SecretParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
421 f!(<SecretParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
422 //f!(<SecretParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
423 //f!(<SecretParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
424 //f!(<SecretParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
425 //f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
426 f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
427 f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
428
429 f!(<SecretParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
430 //f!(<SecretParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
431 f!(<SecretParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
432 //f!(<SecretParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
433 //f!(<SecretParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
434 //f!(<SecretParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
435 f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
436 //f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
437 f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
438
439 f!(<SecretParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
440 f!(<SecretParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
441 //f!(<SecretParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
442 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
443 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
444 //f!(<SecretParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
445 f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
446 f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
447 //f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
448
449 //f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, PrimaryRole>);
450 f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
451 f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
452 //f!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, PrimaryRole>);
453 f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
454 f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
455 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, PrimaryRole>);
456 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
457 //f!(<UnspecifiedParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
458
459 f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
460 //f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, SubordinateRole>);
461 f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
462 f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
463 //f!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, SubordinateRole>);
464 f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
465 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
466 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, SubordinateRole>);
467 //f!(<UnspecifiedParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
468
469 f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
470 f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
471 //f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, UnspecifiedRole>);
472 f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
473 f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
474 //f!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, UnspecifiedRole>);
475 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
476 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
477 //f!(<UnspecifiedParts, UnspecifiedRole> -> <UnspecifiedParts, UnspecifiedRole>);
478
479
480 impl<$($l, )* P, R> $Key<$($l, )* P, R> where P: KeyParts, R: KeyRole
481 {
482 /// Changes the key's role tag to `PrimaryRole`.
483 pub fn role_into_primary(self) -> $Key<$($l, )* P, PrimaryRole> {
484 let mut k: $Key<$($l, )* P, PrimaryRole> = convert!(self);
485 k.set_role(PrimaryRole::role());
486 k
487 }
488
489 /// Changes the key's role tag to `PrimaryRole`.
490 pub fn role_as_primary(&$($l)* self) -> &$($l)* $Key<$($l, )* P, PrimaryRole> {
491 convert_ref!(self)
492 }
493
494 /// Changes the key's role tag to `PrimaryRole`.
495 pub fn role_as_primary_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, PrimaryRole> {
496 convert_ref!(self)
497 }
498
499 /// Changes the key's role tag to `SubordinateRole`.
500 pub fn role_into_subordinate(self) -> $Key<$($l, )* P, SubordinateRole>
501 {
502 let mut k: $Key<$($l, )* P, SubordinateRole> = convert!(self);
503 k.set_role(SubordinateRole::role());
504 k
505 }
506
507 /// Changes the key's role tag to `SubordinateRole`.
508 pub fn role_as_subordinate(&$($l)* self) -> &$($l)* $Key<$($l, )* P, SubordinateRole>
509 {
510 convert_ref!(self)
511 }
512
513 /// Changes the key's role tag to `SubordinateRole`.
514 pub fn role_as_subordinate_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, SubordinateRole>
515 {
516 convert_ref!(self)
517 }
518
519 /// Changes the key's role tag to `UnspecifiedRole`.
520 pub fn role_into_unspecified(self) -> $Key<$($l, )* P, UnspecifiedRole>
521 {
522 let mut k: $Key<$($l, )* P, UnspecifiedRole> = convert!(self);
523 k.set_role(UnspecifiedRole::role());
524 k
525 }
526
527 /// Changes the key's role tag to `UnspecifiedRole`.
528 pub fn role_as_unspecified(&$($l)* self) -> &$($l)* $Key<$($l, )* P, UnspecifiedRole>
529 {
530 convert_ref!(self)
531 }
532
533 /// Changes the key's role tag to `UnspecifiedRole`.
534 pub fn role_as_unspecified_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, UnspecifiedRole>
535 {
536 convert_ref!(self)
537 }
538 }
539 }
540}
541
542create_conversions!(Key<>);
543create_conversions!(Key4<>);
544create_conversions!(Key6<>);
545create_conversions!(KeyBundle<>);
546
547// A hack, since the type has to be an ident, which means that we
548// can't use <>.
549type KeyComponentAmalgamation<'a, P, R> = ComponentAmalgamation<'a, Key<P, R>>;
550create_conversions!(KeyComponentAmalgamation<'a>);
551
552create_part_conversions!(PrimaryKeyAmalgamation<'a;>);
553create_part_conversions!(SubordinateKeyAmalgamation<'a;>);
554create_part_conversions!(ErasedKeyAmalgamation<'a;>);
555create_part_conversions!(ValidPrimaryKeyAmalgamation<'a;>);
556create_part_conversions!(ValidSubordinateKeyAmalgamation<'a;>);
557create_part_conversions!(ValidErasedKeyAmalgamation<'a;>);