use std::marker;
use dope_core::driver::{
receive::{credit, credit::error::Arm},
route::Identity,
schedule::ready,
};
pub mod access;
mod direct;
mod kind;
pub use direct::Direct;
pub(crate) use kind::Kind;
pub trait Flag: Kind {
type Binding<'d, ID: Identity>: Copy;
type Or<Rhs: Flag>: Flag;
type WithParking: Flag;
}
pub trait Credit: Flag {
type Guard<'d>: Unpin + 'd;
}
pub(crate) trait Stored: Flag {
fn arm<'d, ID: Identity>(
binding: Self::Binding<'d, ID>,
ready: ready::Target<'d>,
) -> Result<credit::Pending<'d, ID>, Arm>;
}
pub enum Disabled {}
pub enum Parking {}
pub enum Enabled {}
pub struct Waiting<R>(marker::PhantomData<fn() -> R>);
impl Kind for Disabled {}
impl Kind for Parking {}
impl Kind for Enabled {}
impl<R> Kind for Waiting<R> {}
impl Credit for Disabled {
type Guard<'d> = ();
}
impl Credit for Enabled {
type Guard<'d> = credit::Return<'d>;
}
impl Stored for Enabled {
fn arm<'d, ID: Identity>(
binding: Self::Binding<'d, ID>,
ready: ready::Target<'d>,
) -> Result<credit::Pending<'d, ID>, Arm> {
let (control, target) = binding.into_parts();
control.arm(target, ready)
}
}
impl<R> Stored for Waiting<R> {
fn arm<'d, ID: Identity>(
binding: Self::Binding<'d, ID>,
ready: ready::Target<'d>,
) -> Result<credit::Pending<'d, ID>, Arm> {
let (control, target) = binding.into_parts();
control.arm(target, ready)
}
}
impl Flag for Disabled {
type Binding<'d, ID: Identity> = Direct<'d, ID>;
type Or<Rhs: Flag> = Rhs;
type WithParking = Parking;
}
impl Flag for Parking {
type Binding<'d, ID: Identity> = Direct<'d, ID>;
type Or<Rhs: Flag> = Rhs::WithParking;
type WithParking = Parking;
}
impl Flag for Enabled {
type Binding<'d, ID: Identity> = credit::Binding<'d, ID>;
type Or<Rhs: Flag> = Enabled;
type WithParking = Enabled;
}
impl<R> Flag for Waiting<R> {
type Binding<'d, ID: Identity> = credit::Binding<'d, ID>;
type Or<Rhs: Flag> = Self;
type WithParking = Self;
}