use async_signature::AsyncSigner;
use signature::Signer;
use std::{error::Error, fmt::Debug, future::Future};
use thiserror::Error;
use crate::{codec::Codec, verify::Verify};
pub trait Sign: Verify {
type Signer: Signer<Self::Signature>;
type SignError: Error;
#[allow(clippy::type_complexity)]
#[tracing::instrument(skip_all)]
fn try_sign<T, C: Codec<T>>(
&self,
codec: &C,
signer: &Self::Signer,
payload: &T,
) -> Result<(Self::Signature, Vec<u8>), SignerError<C::EncodingError, Self::SignError>> {
let mut buffer = Vec::new();
codec
.encode_payload(payload, &mut buffer)
.map_err(SignerError::EncodingError)?;
let sig = signer
.try_sign(&buffer)
.map_err(SignerError::SigningError)?;
Ok((sig, buffer))
}
}
pub trait AsyncSign: Verify {
type AsyncSigner: AsyncSigner<Self::Signature>;
type AsyncSignError: Error;
#[allow(clippy::type_complexity)]
#[tracing::instrument(skip_all)]
fn try_sign_async<T, C: Codec<T>>(
&self,
codec: &C,
signer: &Self::AsyncSigner,
payload: &T,
) -> impl Future<
Output = Result<
(Self::Signature, Vec<u8>),
SignerError<C::EncodingError, Self::AsyncSignError>,
>,
> {
async {
let mut buffer = Vec::new();
codec
.encode_payload(payload, &mut buffer)
.map_err(SignerError::EncodingError)?;
let sig = signer
.sign_async(&buffer)
.await
.map_err(SignerError::SigningError)?;
Ok((sig, buffer))
}
}
}
#[derive(Debug, Error)]
pub enum SignerError<Ee: Error, Ve: Error> {
#[error(transparent)]
EncodingError(Ee),
#[error("Signing error: {0}")]
SigningError(signature::Error),
#[error(transparent)]
VarsigError(Ve),
}