use core::fmt;
#[cfg(feature = "dev")]
use arbitrary::Arbitrary;
use meadowcap::raw::InvalidCapability;
use signature::{Keypair, Signer};
use ufotofu::codec_prelude::*;
use crate::{
authorisation::raw::{Delegation, Genesis},
prelude::*,
};
wrapper! {
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "dev", derive(Arbitrary))]
WriteCapability; meadowcap::WriteCapability<MCL, MCC, MPL, NamespaceId, NamespaceSignature, SubspaceId, SubspaceSignature>
}
impl fmt::Debug for WriteCapability {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl WriteCapability {
pub fn receiver(&self) -> &SubspaceId {
self.0.receiver()
}
pub fn granted_namespace(&self) -> &NamespaceId {
self.0.granted_namespace()
}
pub fn granted_area_ref(&self) -> Option<&Area> {
self.0.granted_area_ref().map(Into::into)
}
pub fn genesis(&self) -> &Genesis {
self.0.genesis().into()
}
pub fn is_owned(&self) -> bool {
self.0.is_owned()
}
pub fn delegations(&self) -> &[Delegation] {
let inner_delegations = self.0.delegations();
let as_delegation25_ptr = inner_delegations.as_ptr() as *const Delegation;
unsafe { core::slice::from_raw_parts(as_delegation25_ptr, inner_delegations.len()) }
}
pub fn new_communal(namespace_key: NamespaceId, user_key: SubspaceId) -> Self {
Self(meadowcap::WriteCapability::new_communal(
namespace_key,
user_key,
))
}
pub fn new_owned<NamespaceKeypair>(keypair: &NamespaceKeypair, user_key: SubspaceId) -> Self
where
NamespaceKeypair: Signer<NamespaceSignature> + Keypair<VerifyingKey = NamespaceId>,
{
Self(meadowcap::WriteCapability::new_owned(keypair, user_key))
}
pub fn includes_area(&self, area: &Area) -> bool {
self.0.includes_area(area.into())
}
pub fn granted_area(&self) -> Area {
self.0.granted_area().into()
}
pub fn includes<T>(&self, t: &T) -> bool
where
T: Namespaced + Coordinatelike + ?Sized,
{
self.0.includes(t)
}
pub fn try_delegate<UserKeypair>(
&mut self,
keypair: &UserKeypair,
new_area: Area,
new_receiver: SubspaceId,
) -> Result<(), InvalidCapability>
where
UserKeypair: Signer<SubspaceSignature> + Keypair<VerifyingKey = SubspaceId>,
{
self.0.try_delegate(keypair, new_area.into(), new_receiver)
}
pub fn delegate<UserKeypair>(
&mut self,
keypair: &UserKeypair,
new_area: Area,
new_receiver: SubspaceId,
) where
UserKeypair: Signer<SubspaceSignature> + Keypair<VerifyingKey = SubspaceId>,
{
self.0.delegate(keypair, new_area.into(), new_receiver)
}
}
impl Encodable for WriteCapability {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8> + ?Sized,
{
self.0.encode(consumer).await
}
}
impl EncodableKnownLength for WriteCapability {
fn len_of_encoding(&self) -> usize {
self.0.len_of_encoding()
}
}
impl Decodable for WriteCapability {
type ErrorReason = Blame;
async fn decode<P>(
producer: &mut P,
) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
where
P: BulkProducer<Item = u8> + ?Sized,
Self: Sized,
{
meadowcap::WriteCapability::<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
>::decode(producer)
.await
.map(Into::into)
}
}
impl DecodableCanonic for WriteCapability {
type ErrorCanonic = Blame;
async fn decode_canonic<P>(
producer: &mut P,
) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorCanonic>>
where
P: BulkProducer<Item = u8> + ?Sized,
Self: Sized,
{
meadowcap::WriteCapability::<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
>::decode_canonic(producer)
.await
.map(Into::into)
}
}
wrapper! {
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "dev", derive(Arbitrary))]
PriorCapEntryPair; meadowcap::PriorCapEntryPair<MCL, MCC, MPL, NamespaceId, NamespaceSignature, SubspaceId, SubspaceSignature, PayloadDigest>
}
impl PriorCapEntryPair {
pub fn new(prior_cap: WriteCapability, entry: Entry) -> Self {
let inner_prior_cap: meadowcap::WriteCapability<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
> = prior_cap.into();
let inner_entry: willow_data_model::entry::Entry<
MCL,
MCC,
MPL,
NamespaceId,
SubspaceId,
PayloadDigest,
> = entry.into();
Self(meadowcap::PriorCapEntryPair::new(
inner_prior_cap,
inner_entry,
))
}
pub fn prior_cap(&self) -> &WriteCapability {
<&WriteCapability>::from(self.0.prior_cap())
}
pub fn entry(&self) -> &Entry {
<&Entry>::from(self.0.entry())
}
}
impl RelativeEncodable<PriorCapEntryPair> for WriteCapability {
async fn relative_encode<C>(
&self,
rel: &PriorCapEntryPair,
consumer: &mut C,
) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8> + ?Sized,
{
let inner = <&meadowcap::PriorCapEntryPair<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
PayloadDigest,
>>::from(rel);
self.0.relative_encode(inner, consumer).await
}
fn can_be_encoded_relative_to(&self, rel: &PriorCapEntryPair) -> bool {
let inner = <&meadowcap::PriorCapEntryPair<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
PayloadDigest,
>>::from(rel);
self.0.can_be_encoded_relative_to(inner)
}
}
impl RelativeDecodable<PriorCapEntryPair> for WriteCapability {
type ErrorReason = Blame;
async fn relative_decode<P>(
rel: &PriorCapEntryPair,
producer: &mut P,
) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
where
P: BulkProducer<Item = u8> + ?Sized,
Self: Sized,
{
let inner = meadowcap::WriteCapability::<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
>::relative_decode(
<&meadowcap::PriorCapEntryPair<
MCL,
MCC,
MPL,
NamespaceId,
NamespaceSignature,
SubspaceId,
SubspaceSignature,
PayloadDigest,
>>::from(rel),
producer,
)
.await?;
Ok(Self(inner))
}
}