use crate::Result;
use crate::TPK;
use crate::packet::{key, Signature, Tag};
use crate::serialize::{
PacketRef, Serialize, SerializeInto,
generic_serialize_into, generic_export_into,
};
impl Serialize for TPK {
fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
self.serialize_common(o, false)
}
fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
self.serialize_common(o, true)
}
}
impl TPK {
/// Serializes or exports the TPK.
///
/// If `export` is true, then non-exportable signatures are not
/// written, and components without any exportable binding
/// signature or revocation are not exported.
fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
-> Result<()>
{
PacketRef::PublicKey(self.primary().key()).serialize(o)?;
// Writes a signature if it is exportable or `! export`.
let serialize_sig =
|o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
{
if export {
if sig.exportable_certification().unwrap_or(true) {
PacketRef::Signature(sig).export(o)?;
}
} else {
PacketRef::Signature(sig).serialize(o)?;
}
Ok(())
};
for s in self.primary().selfsigs() {
serialize_sig(o, s)?;
}
for s in self.primary().self_revocations() {
serialize_sig(o, s)?;
}
for s in self.primary().other_revocations() {
serialize_sig(o, s)?;
}
for s in self.primary().certifications() {
serialize_sig(o, s)?;
}
for u in self.userids() {
if export && ! u.selfsigs().iter().chain(u.self_revocations()).any(
|s| s.exportable_certification().unwrap_or(true))
{
// No exportable selfsig on this component, skip it.
continue;
}
PacketRef::UserID(u.userid()).serialize(o)?;
for s in u.self_revocations() {
serialize_sig(o, s)?;
}
for s in u.selfsigs() {
serialize_sig(o, s)?;
}
for s in u.other_revocations() {
serialize_sig(o, s)?;
}
for s in u.certifications() {
serialize_sig(o, s)?;
}
}