use std::collections::BTreeMap;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::document::TrustTask;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Proof {
#[serde(rename = "type")]
pub proof_type: String,
pub cryptosuite: String,
#[serde(rename = "verificationMethod")]
pub verification_method: String,
pub created: DateTime<Utc>,
#[serde(rename = "proofPurpose")]
pub proof_purpose: String,
#[serde(rename = "proofValue")]
pub proof_value: String,
#[serde(flatten)]
pub extra: BTreeMap<String, Value>,
}
#[async_trait::async_trait]
pub trait ProofVerifier: Send + Sync {
async fn verify<P>(&self, doc: &TrustTask<P>) -> Result<(), VerificationError>
where
P: serde::Serialize + Send + Sync;
}
#[derive(Debug, thiserror::Error)]
pub enum VerificationError {
#[error("unsupported cryptosuite: {0}")]
UnsupportedCryptosuite(String),
#[error("malformed proof: {0}")]
MalformedProof(String),
#[error("verification method does not bind to document issuer: {0}")]
IssuerMismatch(String),
#[error("signature verification failed")]
SignatureInvalid,
#[error("proof verification failed: {0}")]
Other(String),
}
#[async_trait::async_trait]
pub trait DynProofVerifier: Send + Sync {
async fn verify_json(
&self,
doc: &TrustTask<serde_json::Value>,
) -> Result<(), VerificationError>;
}
pub struct ErasedVerifier<V>(pub V);
#[async_trait::async_trait]
impl<V: ProofVerifier + Send + Sync> DynProofVerifier for ErasedVerifier<V> {
async fn verify_json(
&self,
doc: &TrustTask<serde_json::Value>,
) -> Result<(), VerificationError> {
<V as ProofVerifier>::verify(&self.0, doc).await
}
}
pub fn erase_verifier<V>(verifier: V) -> std::sync::Arc<dyn DynProofVerifier>
where
V: ProofVerifier + Send + Sync + 'static,
{
std::sync::Arc::new(ErasedVerifier(verifier))
}