use serde::{Serialize, Serializer};
use crate::{exportable::SafeSerialize, private::ControlledPrivate, Controlled, Protected};
use std::marker::PhantomData;
pub struct Usage<T, Scope = DefaultScope>(pub(crate) T, pub(crate) PhantomData<Scope>);
impl<T, S> Usage<T, S> {
pub fn new(x: <Usage<T, S> as Controlled>::Inner) -> Self
where
Self: Controlled,
S: Scope,
{
Self::init_from_inner(x)
}
}
impl<T: ControlledPrivate, Scope> ControlledPrivate for Usage<T, Scope> {}
impl<T, Scope> Controlled for Usage<T, Scope>
where
T: Controlled,
{
fn risky_unwrap(self) -> Self::Inner {
self.0.risky_unwrap()
}
type Inner = T::Inner;
fn init_from_inner(x: Self::Inner) -> Self {
Self(T::init_from_inner(x), PhantomData)
}
fn risky_ref(&self) -> &Self::Inner {
self.0.risky_ref()
}
fn inner_mut(&mut self) -> &mut Self::Inner {
self.0.inner_mut()
}
}
pub trait Scope {}
pub trait Acceptable<S>
where
S: Scope,
{
}
impl<T, S> Acceptable<S> for Usage<T, S> where S: Scope {}
pub struct DefaultScope;
impl Scope for DefaultScope {}
impl<T> Acceptable<DefaultScope> for Protected<T> {}
impl<T, A> Serialize for Usage<T, A>
where
T: Controlled,
T::Inner: SafeSerialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.risky_ref().safe_serialize(serializer)
}
}
#[cfg(test)]
mod tests {
use super::*;
struct MyScope;
impl Scope for MyScope {}
fn example1<T: Acceptable<DefaultScope>>(_: T) -> bool {
true
}
fn example2<T: Acceptable<MyScope>>(_: T) -> bool {
true
}
#[test]
fn test_usage_for_default_scope() {
let x: Usage<Protected<[u8; 32]>, DefaultScope> = Usage::new([0u8; 32]);
assert!(example1(x));
}
#[test]
fn test_usage_for_specific_scope() {
let x: Usage<Protected<[u8; 32]>, MyScope> = Usage::new([0; 32]);
assert!(example2(x));
}
}