use std::convert::TryFrom;
use crate::Error;
use crate::cert::prelude::*;
use crate::packet::prelude::*;
use crate::packet::key::{
KeyParts,
KeyRole,
PrimaryRole,
PublicParts,
SubordinateRole,
SecretParts,
UnspecifiedParts,
UnspecifiedRole
};
use crate::Result;
macro_rules! convert {
( $x:ident ) => {
{ #[allow(clippy::missing_transmute_annotations)]
unsafe { std::mem::transmute($x) }
}
}
}
macro_rules! convert_ref {
( $x:ident ) => {
#[allow(clippy::missing_transmute_annotations)]
unsafe { std::mem::transmute($x) }
}
}
macro_rules! create_part_conversions {
( $Key:ident<$( $l:lifetime ),*; $( $g:ident ),*>) => {
create_part_conversions!($Key<$($l),*; $($g),*> where );
};
( $Key:ident<$( $l:lifetime ),*; $( $g:ident ),*> where $( $w:ident: $c:path ),* ) => {
macro_rules! p {
( <$from_parts:ty> -> <$to_parts:ty> ) => {
impl<$($l, )* $($g, )* > From<$Key<$($l, )* $from_parts, $($g, )* >> for $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
fn from(p: $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
convert!(p)
}
}
impl<$($l, )* $($g, )* > From<&$($l)* $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
fn from(p: &$($l)* $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
convert_ref!(p)
}
}
impl<$($l, )* $($g, )* > From<&$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* mut $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
fn from(p: &$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >) -> Self {
convert_ref!(p)
}
}
}
}
macro_rules! p_try {
( <$from_parts:ty> -> <$to_parts:ty>) => {
impl<$($l, )* $($g, )* > TryFrom<$Key<$($l, )* $from_parts, $($g, )* >> for $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
type Error = anyhow::Error;
fn try_from(p: $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
p.parts_into_secret()
}
}
impl<$($l, )* $($g, )* > TryFrom<&$($l)* $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
type Error = anyhow::Error;
fn try_from(p: &$($l)* $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
if p.has_secret() {
Ok(convert_ref!(p))
} else {
Err(Error::InvalidArgument("No secret key".into())
.into())
}
}
}
impl<$($l, )* $($g, )* > TryFrom<&$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >> for &$($l)* mut $Key<$($l, )* $to_parts, $($g, )* >
where $($w: $c ),*
{
type Error = anyhow::Error;
fn try_from(p: &$($l)* mut $Key<$($l, )* $from_parts, $($g, )* >) -> Result<Self> {
if p.has_secret() {
Ok(convert_ref!(p))
} else {
Err(Error::InvalidArgument("No secret key".into())
.into())
}
}
}
}
}
p_try!(<PublicParts> -> <SecretParts>);
p!(<PublicParts> -> <UnspecifiedParts>);
p!(<SecretParts> -> <PublicParts>);
p!(<SecretParts> -> <UnspecifiedParts>);
p!(<UnspecifiedParts> -> <PublicParts>);
p_try!(<UnspecifiedParts> -> <SecretParts>);
impl<$($l, )* P, $($g, )*> $Key<$($l, )* P, $($g, )*> where P: KeyParts, $($w: $c ),*
{
pub fn parts_into_public(self) -> $Key<$($l, )* PublicParts, $($g, )*> {
convert!(self)
}
pub fn parts_as_public(&$($l)* self) -> &$($l)* $Key<$($l, )* PublicParts, $($g, )*> {
convert_ref!(self)
}
pub fn parts_as_public_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* PublicParts, $($g, )*> {
convert_ref!(self)
}
pub fn parts_into_secret(self) -> Result<$Key<$($l, )* SecretParts, $($g, )*>> {
if self.has_secret() {
Ok(convert!(self))
} else {
Err(Error::InvalidArgument("No secret key".into()).into())
}
}
pub fn parts_as_secret(&$($l)* self) -> Result<&$($l)* $Key<$($l, )* SecretParts, $($g, )*>>
{
if self.has_secret() {
Ok(convert_ref!(self))
} else {
Err(Error::InvalidArgument("No secret key".into()).into())
}
}
pub fn parts_as_secret_mut(&$($l)* mut self) -> Result<&$($l)* mut $Key<$($l, )* SecretParts, $($g, )*>>
{
if self.has_secret() {
Ok(convert_ref!(self))
} else {
Err(Error::InvalidArgument("No secret key".into()).into())
}
}
pub fn parts_into_unspecified(self) -> $Key<$($l, )* UnspecifiedParts, $($g, )*> {
convert!(self)
}
pub fn parts_as_unspecified(&$($l)* self) -> &$($l)* $Key<$($l, )* UnspecifiedParts, $($g, )*> {
convert_ref!(self)
}
pub fn parts_as_unspecified_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* UnspecifiedParts, $($g, )*> {
convert_ref!(self)
}
}
}
}
macro_rules! create_role_conversions {
( $Key:ident<$( $l:lifetime ),*> ) => {
macro_rules! r {
( <$from_role:ty> -> <$to_role:ty>) => {
impl<$($l, )* P> From<$Key<$($l, )* P, $from_role>> for $Key<$($l, )* P, $to_role>
where P: KeyParts
{
fn from(p: $Key<$($l, )* P, $from_role>) -> Self {
let mut k: Self = convert!(p);
k.set_role(<$to_role>::role());
k
}
}
impl<$($l, )* P> From<&$($l)* $Key<$($l, )* P, $from_role>> for &$($l)* $Key<$($l, )* P, $to_role>
where P: KeyParts
{
fn from(p: &$($l)* $Key<$($l, )* P, $from_role>) -> Self {
convert_ref!(p)
}
}
impl<$($l, )* P> From<&$($l)* mut $Key<$($l, )* P, $from_role>> for &$($l)* mut $Key<$($l, )* P, $to_role>
where P: KeyParts
{
fn from(p: &$($l)* mut $Key<$($l, )* P, $from_role>) -> Self {
convert_ref!(p)
}
}
}
}
r!(<PrimaryRole> -> <SubordinateRole>);
r!(<PrimaryRole> -> <UnspecifiedRole>);
r!(<SubordinateRole> -> <PrimaryRole>);
r!(<SubordinateRole> -> <UnspecifiedRole>);
r!(<UnspecifiedRole> -> <PrimaryRole>);
r!(<UnspecifiedRole> -> <SubordinateRole>);
}
}
macro_rules! create_conversions {
( $Key:ident<$( $l:lifetime ),*> ) => {
create_part_conversions!($Key<$($l ),* ; R> where R: KeyRole);
create_role_conversions!($Key<$($l ),* >);
macro_rules! f {
( <$from_parts:ty, $from_role:ty> -> <$to_parts:ty, $to_role:ty> ) => {
impl<$($l ),*> From<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* $to_parts, $to_role>
{
fn from(p: $Key<$($l, )* $from_parts, $from_role>) -> Self {
let mut k: Self = convert!(p);
k.set_role(<$to_role>::role());
k
}
}
impl<$($l ),*> From<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* $to_parts, $to_role>
{
fn from(p: &$($l)* $Key<$from_parts, $from_role>) -> Self {
convert_ref!(p)
}
}
impl<$($l ),*> From<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* $to_parts, $to_role>
{
fn from(p: &$($l)* mut $Key<$from_parts, $from_role>) -> Self {
convert_ref!(p)
}
}
}
}
macro_rules! f_try {
( <$from_parts:ty, $from_role:ty> -> <SecretParts, $to_role:ty> ) => {
impl<$($l ),*> TryFrom<$Key<$($l, )* $from_parts, $from_role>> for $Key<$($l, )* SecretParts, $to_role>
{
type Error = anyhow::Error;
fn try_from(p: $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
let mut k: $Key<$($l, )* $from_parts, $to_role> = p.into();
k.set_role(<$to_role>::role());
k.try_into()
}
}
impl<$($l ),*> TryFrom<&$($l)* $Key<$($l, )* $from_parts, $from_role>> for &$($l)* $Key<$($l, )* SecretParts, $to_role>
{
type Error = anyhow::Error;
fn try_from(p: &$($l)* $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
let k: &$($l)* $Key<$($l, )* $from_parts, $to_role> = p.into();
k.try_into()
}
}
impl<$($l ),*> TryFrom<&$($l)* mut $Key<$($l, )* $from_parts, $from_role>> for &$($l)* mut $Key<$($l, )* SecretParts, $to_role>
{
type Error = anyhow::Error;
fn try_from(p: &$($l)* mut $Key<$($l, )* $from_parts, $from_role>) -> Result<Self> {
let k: &$($l)* mut $Key<$($l, )* $from_parts, $to_role> = p.into();
k.try_into()
}
}
}
}
f_try!(<PublicParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
f_try!(<PublicParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
f!(<PublicParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
f_try!(<PublicParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
f_try!(<PublicParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
f!(<PublicParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
f_try!(<PublicParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
f!(<PublicParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
f!(<SecretParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
f!(<SecretParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, SubordinateRole>);
f!(<SecretParts, PrimaryRole> -> <UnspecifiedParts, UnspecifiedRole>);
f!(<SecretParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
f!(<SecretParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, PrimaryRole>);
f!(<SecretParts, SubordinateRole> -> <UnspecifiedParts, UnspecifiedRole>);
f!(<SecretParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
f!(<SecretParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, PrimaryRole>);
f!(<SecretParts, UnspecifiedRole> -> <UnspecifiedParts, SubordinateRole>);
f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, SubordinateRole>);
f!(<UnspecifiedParts, PrimaryRole> -> <PublicParts, UnspecifiedRole>);
f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, SubordinateRole>);
f_try!(<UnspecifiedParts, PrimaryRole> -> <SecretParts, UnspecifiedRole>);
f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, PrimaryRole>);
f!(<UnspecifiedParts, SubordinateRole> -> <PublicParts, UnspecifiedRole>);
f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, PrimaryRole>);
f_try!(<UnspecifiedParts, SubordinateRole> -> <SecretParts, UnspecifiedRole>);
f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, PrimaryRole>);
f!(<UnspecifiedParts, UnspecifiedRole> -> <PublicParts, SubordinateRole>);
f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, PrimaryRole>);
f_try!(<UnspecifiedParts, UnspecifiedRole> -> <SecretParts, SubordinateRole>);
impl<$($l, )* P, R> $Key<$($l, )* P, R> where P: KeyParts, R: KeyRole
{
pub fn role_into_primary(self) -> $Key<$($l, )* P, PrimaryRole> {
let mut k: $Key<$($l, )* P, PrimaryRole> = convert!(self);
k.set_role(PrimaryRole::role());
k
}
pub fn role_as_primary(&$($l)* self) -> &$($l)* $Key<$($l, )* P, PrimaryRole> {
convert_ref!(self)
}
pub fn role_as_primary_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, PrimaryRole> {
convert_ref!(self)
}
pub fn role_into_subordinate(self) -> $Key<$($l, )* P, SubordinateRole>
{
let mut k: $Key<$($l, )* P, SubordinateRole> = convert!(self);
k.set_role(SubordinateRole::role());
k
}
pub fn role_as_subordinate(&$($l)* self) -> &$($l)* $Key<$($l, )* P, SubordinateRole>
{
convert_ref!(self)
}
pub fn role_as_subordinate_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, SubordinateRole>
{
convert_ref!(self)
}
pub fn role_into_unspecified(self) -> $Key<$($l, )* P, UnspecifiedRole>
{
let mut k: $Key<$($l, )* P, UnspecifiedRole> = convert!(self);
k.set_role(UnspecifiedRole::role());
k
}
pub fn role_as_unspecified(&$($l)* self) -> &$($l)* $Key<$($l, )* P, UnspecifiedRole>
{
convert_ref!(self)
}
pub fn role_as_unspecified_mut(&$($l)* mut self) -> &$($l)* mut $Key<$($l, )* P, UnspecifiedRole>
{
convert_ref!(self)
}
}
}
}
create_conversions!(Key<>);
create_conversions!(Key4<>);
create_conversions!(Key6<>);
create_conversions!(KeyBundle<>);
type KeyComponentAmalgamation<'a, P, R> = ComponentAmalgamation<'a, Key<P, R>>;
create_conversions!(KeyComponentAmalgamation<'a>);
create_part_conversions!(PrimaryKeyAmalgamation<'a;>);
create_part_conversions!(SubordinateKeyAmalgamation<'a;>);
create_part_conversions!(ErasedKeyAmalgamation<'a;>);
create_part_conversions!(ValidPrimaryKeyAmalgamation<'a;>);
create_part_conversions!(ValidSubordinateKeyAmalgamation<'a;>);
create_part_conversions!(ValidErasedKeyAmalgamation<'a;>);