use std::fmt;
use quickcheck::{Arbitrary, Gen};
use Error;
use Packet;
use packet;
use packet::Signature;
use Result;
use KeyID;
use HashAlgorithm;
use PublicKeyAlgorithm;
use SignatureType;
use serialize::SerializeInto;
#[derive(Eq, Hash, Clone)]
pub struct OnePassSig3 {
pub(crate) common: packet::Common,
sigtype: SignatureType,
hash_algo: HashAlgorithm,
pk_algo: PublicKeyAlgorithm,
issuer: KeyID,
last: u8,
}
impl fmt::Debug for OnePassSig3 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("OnePassSig3")
.field("sigtype", &self.sigtype)
.field("hash_algo", &self.hash_algo)
.field("pk_algo", &self.pk_algo)
.field("issuer", &self.issuer)
.field("last", &self.last)
.finish()
}
}
impl PartialEq for OnePassSig3 {
fn eq(&self, other: &OnePassSig3) -> bool {
if let (Ok(a), Ok(b)) = (self.to_vec(), other.to_vec()) {
a == b
} else {
false
}
}
}
impl OnePassSig3 {
pub fn new(sigtype: SignatureType) -> Self {
OnePassSig3 {
common: Default::default(),
sigtype: sigtype,
hash_algo: HashAlgorithm::Unknown(0),
pk_algo: PublicKeyAlgorithm::Unknown(0),
issuer: KeyID::new(0),
last: 1,
}
}
pub fn sigtype(&self) -> SignatureType {
self.sigtype
}
pub fn set_sigtype(&mut self, t: SignatureType) -> SignatureType {
::std::mem::replace(&mut self.sigtype, t)
}
pub fn pk_algo(&self) -> PublicKeyAlgorithm {
self.pk_algo
}
pub fn set_pk_algo(&mut self, algo: PublicKeyAlgorithm) -> PublicKeyAlgorithm {
::std::mem::replace(&mut self.pk_algo, algo)
}
pub fn hash_algo(&self) -> HashAlgorithm {
self.hash_algo
}
pub fn set_hash_algo(&mut self, algo: HashAlgorithm) -> HashAlgorithm {
::std::mem::replace(&mut self.hash_algo, algo)
}
pub fn issuer(&self) -> &KeyID {
&self.issuer
}
pub fn set_issuer(&mut self, issuer: KeyID) -> KeyID {
::std::mem::replace(&mut self.issuer, issuer)
}
pub fn last(&self) -> bool {
self.last > 0
}
pub fn set_last(&mut self, last: bool) -> bool {
::std::mem::replace(&mut self.last, if last { 1 } else { 0 }) > 0
}
pub fn last_raw(&self) -> u8 {
self.last
}
pub fn set_last_raw(&mut self, last: u8) -> u8 {
::std::mem::replace(&mut self.last, last)
}
}
impl From<OnePassSig3> for super::OnePassSig {
fn from(s: OnePassSig3) -> Self {
super::OnePassSig::V3(s)
}
}
impl From<OnePassSig3> for Packet {
fn from(p: OnePassSig3) -> Self {
super::OnePassSig::from(p).into()
}
}
impl<'a> From<&'a Signature> for Result<OnePassSig3> {
fn from(s: &'a Signature) -> Self {
let issuer = match s.issuer() {
Some(i) => i,
None =>
return Err(Error::InvalidArgument(
"Signature has no issuer".into()).into()),
};
Ok(OnePassSig3 {
common: Default::default(),
sigtype: s.sigtype(),
hash_algo: s.hash_algo(),
pk_algo: s.pk_algo(),
issuer: issuer,
last: 0,
})
}
}
impl Arbitrary for OnePassSig3 {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let mut ops = OnePassSig3::new(SignatureType::arbitrary(g));
ops.set_hash_algo(HashAlgorithm::arbitrary(g));
ops.set_pk_algo(PublicKeyAlgorithm::arbitrary(g));
ops.set_issuer(KeyID::arbitrary(g));
ops.set_last_raw(u8::arbitrary(g));
ops
}
}
#[cfg(test)]
mod tests {
use super::*;
use parse::Parse;
use serialize::SerializeInto;
quickcheck! {
fn roundtrip(p: OnePassSig3) -> bool {
let q = OnePassSig3::from_bytes(&p.to_vec().unwrap()).unwrap();
assert_eq!(p, q);
true
}
}
}