use num_enum::{FromPrimitive, IntoPrimitive};
use sequoia_openpgp::Cert;
use sequoia_openpgp::types::SignatureType;
use serde::Serialize;
use serialize_display_adapter_macro_derive::JsonSerializeDisplayAdapter;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::sync::Arc;
#[derive(Debug, Clone, Serialize, JsonSerializeDisplayAdapter)]
pub struct OpenPgpKey {
pub id: Arc<String>,
pub is_revoked: bool,
pub is_expired: bool,
pub user_ids: HashMap<Arc<String>, OpenPgpUid>,
pub primary_user_id: Arc<String>,
#[serde(skip_serializing)]
pub original_cert: Arc<Cert>,
}
impl PartialEq for OpenPgpKey {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for OpenPgpKey {}
impl Hash for OpenPgpKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl Borrow<str> for OpenPgpKey {
fn borrow(&self) -> &str {
self.id.as_str()
}
}
#[derive(Debug, Clone, Serialize)]
pub struct OpenPgpUid {
pub fingerprint: Arc<String>,
pub uid: Arc<String>,
pub name: String,
pub email: String,
pub comment: String,
#[serde(skip_serializing)]
pub sig_vec: Vec<OpenPgpSig>,
pub is_revoked: bool,
pub is_primary: bool,
#[serde(skip_serializing)]
pub original_cert: Arc<Cert>,
}
impl PartialEq for OpenPgpUid {
fn eq(&self, other: &Self) -> bool {
self.fingerprint == other.fingerprint && self.uid == other.uid
}
}
impl Eq for OpenPgpUid {}
impl Hash for OpenPgpUid {
fn hash<H: Hasher>(&self, state: &mut H) {
self.fingerprint.hash(state);
self.uid.hash(state);
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)]
pub struct GraphNodeUid<'a> {
pub fingerprint: &'a str,
pub uid: &'a str,
}
pub(crate) trait OpenPgpUidKey {
fn key(&self) -> &str;
fn uid(&self) -> &str;
}
impl<'a> Borrow<dyn OpenPgpUidKey + 'a> for OpenPgpUid {
fn borrow(&self) -> &(dyn OpenPgpUidKey + 'a) {
self
}
}
impl<'a> Borrow<dyn OpenPgpUidKey + 'a> for OpenPgpSig {
fn borrow(&self) -> &(dyn OpenPgpUidKey + 'a) {
self
}
}
impl Hash for dyn OpenPgpUidKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key().hash(state);
self.uid().hash(state);
}
}
impl PartialEq for dyn OpenPgpUidKey {
fn eq(&self, other: &Self) -> bool {
self.key() == other.key() && self.uid() == other.uid()
}
}
impl Eq for dyn OpenPgpUidKey {}
impl OpenPgpUidKey for OpenPgpUid {
fn key(&self) -> &str {
&self.fingerprint
}
fn uid(&self) -> &str {
&self.uid
}
}
impl OpenPgpUidKey for &OpenPgpUid {
fn key(&self) -> &str {
self.fingerprint.as_str()
}
fn uid(&self) -> &str {
self.uid.as_str()
}
}
impl OpenPgpUidKey for OpenPgpSig {
fn key(&self) -> &str {
self.fingerprint.as_str()
}
fn uid(&self) -> &str {
self.uid.as_str()
}
}
impl OpenPgpUidKey for &OpenPgpSig {
fn key(&self) -> &str {
self.fingerprint.as_str()
}
fn uid(&self) -> &str {
self.uid.as_str()
}
}
impl OpenPgpUidKey for GraphNodeUid<'_> {
fn key(&self) -> &str {
self.fingerprint
}
fn uid(&self) -> &str {
self.uid
}
}
impl OpenPgpUidKey for &GraphNodeUid<'_> {
fn key(&self) -> &str {
self.fingerprint
}
fn uid(&self) -> &str {
self.uid
}
}
impl<'a> From<&'a OpenPgpUid> for GraphNodeUid<'a> {
fn from(value: &'a OpenPgpUid) -> Self {
GraphNodeUid {
fingerprint: value.fingerprint.as_str(),
uid: value.uid.as_str(),
}
}
}
impl<'a> From<&&'a OpenPgpUid> for GraphNodeUid<'a> {
fn from(value: &&'a OpenPgpUid) -> Self {
GraphNodeUid {
fingerprint: value.fingerprint.as_str(),
uid: value.uid.as_str(),
}
}
}
impl<'a> From<&'a OpenPgpSig> for GraphNodeUid<'a> {
fn from(value: &'a OpenPgpSig) -> Self {
GraphNodeUid {
fingerprint: value.fingerprint.as_str(),
uid: value.uid.as_str(),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub struct OpenPgpSig {
pub fingerprint: String,
pub uid: String,
pub trust_level: u8,
pub trust_value: OpenPgpSigTrust,
pub sig_type: SigType,
pub creation_time: u64,
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub struct GraphEdgeSig {
pub(crate) trust_level: u8,
pub(crate) trust_value: OpenPgpSigTrust,
pub(crate) sig_type: SigType,
pub(crate) creation_time: u64,
}
impl From<&OpenPgpSig> for GraphEdgeSig {
fn from(value: &OpenPgpSig) -> Self {
GraphEdgeSig {
trust_level: value.trust_level,
trust_value: value.trust_value,
sig_type: value.sig_type,
creation_time: value.creation_time,
}
}
}
#[derive(
IntoPrimitive,
FromPrimitive,
Ord,
PartialOrd,
Eq,
PartialEq,
Debug,
Copy,
Clone,
Default,
Serialize,
JsonSerializeDisplayAdapter,
)]
#[repr(u8)]
pub(crate) enum OpenPgpValidity {
#[default]
Unknown = 0,
Undefined = 1,
Never = 2,
Marginal = 3,
Full = 4,
Ultimate = 5,
}
#[derive(
FromPrimitive,
IntoPrimitive,
Ord,
PartialOrd,
Eq,
PartialEq,
Debug,
Copy,
Clone,
Default,
Serialize,
JsonSerializeDisplayAdapter,
)]
#[repr(u8)]
pub enum OpenPgpSigTrust {
#[default]
None = 0,
#[num_enum(alternatives = [1..60, 61..120])]
Partial = 60,
#[num_enum(alternatives = [121..=255])]
Complete = 120,
}
#[derive(
FromPrimitive,
IntoPrimitive,
Ord,
PartialOrd,
Eq,
PartialEq,
Debug,
Copy,
Clone,
Serialize,
JsonSerializeDisplayAdapter,
)]
#[repr(u8)]
pub enum SigType {
Default = 0x10,
NotAtAll = 0x11,
Casual = 0x12,
Careful = 0x13,
Revoke = 0x30,
#[num_enum(catch_all)]
Unknown(u8),
}
impl From<SignatureType> for SigType {
fn from(value: SignatureType) -> Self {
match value {
SignatureType::GenericCertification => SigType::Default,
SignatureType::PersonaCertification => SigType::NotAtAll,
SignatureType::CasualCertification => SigType::Casual,
SignatureType::PositiveCertification => SigType::Careful,
SignatureType::CertificationRevocation => SigType::Revoke,
_ => SigType::Unknown(value.into()),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)]
pub struct GraphNodeUidOwned {
pub fingerprint: String,
pub uid: String,
}
impl<'a> From<&'a GraphNodeUidOwned> for GraphNodeUid<'a> {
fn from(value: &'a GraphNodeUidOwned) -> Self {
GraphNodeUid {
fingerprint: value.fingerprint.as_str(),
uid: value.uid.as_str(),
}
}
}