#[cfg(feature = "dev")]
use arbitrary::Arbitrary;
use crate::{
entry::{Entry, Entrylike, EntrylikeExt},
prelude::{Coordinatelike, Keylike, Namespaced},
};
pub trait AuthorisationToken<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD>:
Sized
{
type Ingredients;
type CreationError;
fn new_for_entry<E>(
entry: &E,
ingredients: &Self::Ingredients,
) -> Result<Self, Self::CreationError>
where
E: EntrylikeExt<MCL, MCC, MPL, N, S, PD> + ?Sized;
fn does_authorise<E>(&self, entry: &E) -> bool
where
E: EntrylikeExt<MCL, MCC, MPL, N, S, PD> + ?Sized;
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
#[cfg_attr(feature = "dev", derive(Arbitrary))]
pub struct PossiblyAuthorisedEntry<
const MCL: usize,
const MCC: usize,
const MPL: usize,
N,
S,
PD,
AT,
> {
pub entry: Entry<MCL, MCC, MPL, N, S, PD>,
pub authorisation_token: AT,
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
PossiblyAuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
pub fn into_authorised_entry(self) -> Result<AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>, Self>
where
AT: AuthorisationToken<MCL, MCC, MPL, N, S, PD>,
{
if self.authorisation_token.does_authorise(&self.entry) {
Ok(AuthorisedEntry {
entry: self.entry,
authorisation_token: self.authorisation_token,
})
} else {
Err(self)
}
}
pub unsafe fn into_authorised_entry_unchecked(
self,
) -> AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT> {
AuthorisedEntry {
entry: self.entry,
authorisation_token: self.authorisation_token,
}
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT> Keylike<MCL, MCC, MPL, S>
for PossiblyAuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_subspace_id(&self) -> &S {
self.entry.wdm_subspace_id()
}
fn wdm_path(&self) -> &crate::prelude::Path<MCL, MCC, MPL> {
self.entry.wdm_path()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
Coordinatelike<MCL, MCC, MPL, S> for PossiblyAuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_timestamp(&self) -> crate::Timestamp {
self.entry.wdm_timestamp()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT> Namespaced<N>
for PossiblyAuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_namespace_id(&self) -> &N {
self.entry.wdm_namespace_id()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
Entrylike<MCL, MCC, MPL, N, S, PD> for PossiblyAuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_payload_length(&self) -> u64 {
self.entry.wdm_payload_length()
}
fn wdm_payload_digest(&self) -> &PD {
self.entry.wdm_payload_digest()
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
#[cfg_attr(feature = "dev", derive(Arbitrary))]
pub struct AuthorisedEntry<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT> {
entry: Entry<MCL, MCC, MPL, N, S, PD>,
authorisation_token: AT,
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
pub fn into_parts(self) -> (Entry<MCL, MCC, MPL, N, S, PD>, AT) {
(self.entry, self.authorisation_token)
}
pub fn entry(&self) -> &Entry<MCL, MCC, MPL, N, S, PD> {
&self.entry
}
pub fn authorisation_token(&self) -> &AT {
&self.authorisation_token
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT> Keylike<MCL, MCC, MPL, S>
for AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_subspace_id(&self) -> &S {
self.entry.wdm_subspace_id()
}
fn wdm_path(&self) -> &crate::prelude::Path<MCL, MCC, MPL> {
self.entry.wdm_path()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
Coordinatelike<MCL, MCC, MPL, S> for AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_timestamp(&self) -> crate::Timestamp {
self.entry.wdm_timestamp()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT> Namespaced<N>
for AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_namespace_id(&self) -> &N {
self.entry.wdm_namespace_id()
}
}
impl<const MCL: usize, const MCC: usize, const MPL: usize, N, S, PD, AT>
Entrylike<MCL, MCC, MPL, N, S, PD> for AuthorisedEntry<MCL, MCC, MPL, N, S, PD, AT>
{
fn wdm_payload_length(&self) -> u64 {
self.entry.wdm_payload_length()
}
fn wdm_payload_digest(&self) -> &PD {
self.entry.wdm_payload_digest()
}
}