#[cfg(feature = "dev")]
use arbitrary::Arbitrary;
use ufotofu::codec_prelude::*;
use super::RawCapability;
use crate::{
authorisation::{
ReadCapability,
raw::{AccessMode, Delegation, Genesis, InvalidCapability},
},
prelude::*,
};
#[derive(Clone, PartialEq, Eq)]
pub struct PossiblyValidReadCapability {
pub(crate) inner: RawCapability,
}
impl core::fmt::Debug for PossiblyValidReadCapability {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PossiblyValidReadCapability")
.field("genesis", &self.inner.genesis)
.field("delegations", &self.inner.delegations)
.finish()
}
}
impl PossiblyValidReadCapability {
pub fn receiver(&self) -> &SubspaceId {
self.inner.receiver()
}
pub fn granted_namespace(&self) -> &NamespaceId {
self.inner.granted_namespace()
}
pub fn granted_area_ref(&self) -> Option<&Area> {
self.inner.granted_area_ref()
}
pub fn genesis(&self) -> &Genesis {
self.inner.genesis()
}
pub fn is_owned(&self) -> bool {
self.inner.is_owned()
}
pub fn delegations(&self) -> &[Delegation] {
self.inner.delegations()
}
pub fn new_communal(namespace_key: NamespaceId, user_key: SubspaceId) -> Self {
Self {
inner: RawCapability::new_communal(super::AccessMode::Read, namespace_key, user_key),
}
}
pub fn new_owned(
namespace_key: NamespaceId,
user_key: SubspaceId,
initial_authorisation: NamespaceSignature,
) -> Self {
Self {
inner: RawCapability::new_owned(
super::AccessMode::Read,
namespace_key,
user_key,
initial_authorisation,
),
}
}
pub unsafe fn into_read_capability_unchecked(self) -> ReadCapability {
ReadCapability { inner: self }
}
pub fn includes_area(&self, area: &Area) -> bool {
self.inner.includes_area(area)
}
pub fn try_append_delegation(
&mut self,
delegation: Delegation,
) -> Result<(), InvalidCapability> {
self.inner.try_append_delegation(delegation)
}
pub fn append_delegation(&mut self, delegation: Delegation) {
self.inner.append_delegation(delegation)
}
pub fn try_append_delegation_checking_validity(
&mut self,
delegation: Delegation,
) -> Result<(), InvalidCapability> {
self.inner
.try_append_delegation_checking_validity(delegation)
}
pub fn append_delegation_checking_validity(&mut self, delegation: Delegation) {
self.try_append_delegation_checking_validity(delegation)
.unwrap()
}
pub fn granted_area(&self) -> Area {
self.inner.granted_area()
}
pub fn includes<T>(&self, t: &T) -> bool
where
T: Namespaced + Coordinatelike + ?Sized,
{
self.inner.includes(t)
}
pub fn is_valid(&self) -> bool {
self.inner.is_valid()
}
#[allow(clippy::result_large_err)]
pub fn into_read_capability(self) -> Result<ReadCapability, Self> {
if self.is_valid() {
Ok(
unsafe { self.into_read_capability_unchecked() },
)
} else {
Err(self)
}
}
}
impl Encodable for PossiblyValidReadCapability {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8> + ?Sized,
{
self.inner.encode(consumer).await
}
}
impl EncodableKnownLength for PossiblyValidReadCapability {
fn len_of_encoding(&self) -> usize {
self.inner.len_of_encoding()
}
}
impl Decodable for PossiblyValidReadCapability {
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,
{
let decoded: RawCapability = producer.produce_decoded().await?;
if decoded.access_mode() == AccessMode::Read {
Ok(Self { inner: decoded })
} else {
Err(DecodeError::Other(Blame::TheirFault))
}
}
}
impl DecodableCanonic for PossiblyValidReadCapability {
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,
{
let decoded: RawCapability = producer.produce_decoded_canonic().await?;
if decoded.access_mode() == AccessMode::Read {
Ok(Self { inner: decoded })
} else {
Err(DecodeError::Other(Blame::TheirFault))
}
}
}
#[cfg(feature = "dev")]
impl<'a> Arbitrary<'a> for PossiblyValidReadCapability {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
let mut raw_cap: RawCapability = Arbitrary::arbitrary(u)?;
match raw_cap.genesis {
Genesis::Communal(super::CommunalGenesis {
ref mut access_mode,
..
}) => {
*access_mode = AccessMode::Read;
}
Genesis::Owned(super::OwnedGenesis {
ref mut access_mode,
..
}) => {
*access_mode = AccessMode::Read;
}
}
Ok(Self { inner: raw_cap })
}
}
impl From<ReadCapability> for PossiblyValidReadCapability {
fn from(value: ReadCapability) -> Self {
value.inner
}
}