// Copyright 2020-2021 Ian Jackson and contributors to Otter // SPDX-License-Identifier: AGPL-3.0-or-later // There is NO WARRANTY. use crate::prelude::*; #[derive(Copy,Clone,Debug)] pub struct Global; #[derive(Debug,Copy,Clone)] pub struct Unauthorised (T, PhantomData); impl Unauthorised { #[inline] pub fn of(t: T) -> Self { Unauthorised(t, PhantomData) } #[inline] pub fn by(self, _auth: Authorisation) -> T { self.0 } #[inline] pub fn by_ref(&self, _auth: Authorisation) -> & T { & self.0 } #[inline] pub fn by_mut(&mut self, _auth: Authorisation) -> &mut T { &mut self.0 } } impl From for Unauthorised { #[inline] fn from(t: T) -> Self { Self::of(t) } } #[derive(Error,Debug)] #[error("internal AuthorisationError {0}")] pub struct AuthorisationError(pub String); #[derive(Debug)] pub struct Authorisation (PhantomData<*const A>); impl Clone for Authorisation { #[inline] fn clone(&self)->Self{ *self }} impl Copy for Authorisation { } pub type AuthorisationSuperuser = Authorisation; impl Authorisation { /// Proof obligation: access to this `T` has been authorised. #[inline] pub const fn promise_for(_v: &T) -> Authorisation { Authorisation(PhantomData) } #[inline] pub fn map(self, _f: F) -> Authorisation where F: Fn(&T) -> &U { self.so_promise() } /// Minor proof obligation: in this case, authorised access to `T` /// implies authorised access to `U`. #[inline] pub fn so_promise(self) -> Authorisation { Authorisation(PhantomData) } /// Proof obligation: access to `T` has been authorised. #[inline] pub const fn promise_any() -> Authorisation { Authorisation(PhantomData) } } impl From> for Authorisation { // ^ we need a bound not met by Global or we conflict with From for T #[inline] fn from(global: Authorisation) -> Self { global.so_promise() } } impl From for AuthorisationError { fn from(a: anyhow::Error) -> AuthorisationError { AuthorisationError(format!("{}", a)) } } pub trait AuthorisationCombine: Sized { type Output; #[inline] fn combine(self) -> Authorisation { Authorisation(PhantomData) } } impl AuthorisationCombine for (Authorisation, Authorisation) { type Output = (A, B); } impl AuthorisationCombine for (Authorisation, Authorisation, Authorisation) { type Output = (A, B, C); }