use std::time::SystemTime;
use generic_array::ArrayLength;
use typenum::Unsigned;
use crate::algorithm::{Signature, Signer as AlgorithmSigner};
use crate::error::BadSignature;
use crate::{BadTimedSignature, Separator, UnsignedValue};
pub trait Signer {
fn sign<S: AsRef<str>>(&self, value: S) -> String;
fn unsign<'a>(&'a self, value: &'a str) -> Result<&'a str, BadSignature<'a>>;
fn separator(&self) -> Separator;
fn verify_encoded_signature(&self, value: &[u8], encoded_signature: &[u8]) -> bool;
fn signature_output_size(&self) -> usize;
}
pub trait GetSigner {
type OutputSize: ArrayLength<u8> + Unsigned;
type Signer: AlgorithmSigner<OutputSize = Self::OutputSize>;
fn get_signer(&self) -> Self::Signer;
fn get_signature(&self, value: &[u8]) -> Signature<Self::OutputSize> {
self.get_signer().input_chained(value).sign()
}
}
pub trait TimestampSigner {
fn separator(&self) -> Separator;
fn sign_with_timestamp<S: AsRef<str>>(&self, value: S, timestamp: SystemTime) -> String;
fn sign<S: AsRef<str>>(&self, value: S) -> String;
fn unsign<'a>(&'a self, value: &'a str) -> Result<UnsignedValue, BadTimedSignature<'a>>;
}
pub trait IntoTimestampSigner {
type TimestampSigner: TimestampSigner;
fn into_timestamp_signer(self) -> Self::TimestampSigner;
}
pub trait AsSigner {
type Signer: Signer;
fn as_signer(&self) -> &Self::Signer;
}