use std::mem;
use dope_core::driver::route::{indices, table};
pub trait Policy {
type State: Default + State;
const AUTHORITATIVE: bool;
}
#[derive(Default)]
pub struct Frozen;
#[derive(Default)]
pub struct Scan {
slots: Option<table::Iter>,
}
pub trait State {
fn scan(&mut self) -> Option<&mut Scan>;
fn next(&mut self) -> Option<indices::SlotIndex>;
fn is_pending(&self) -> bool;
}
impl Scan {
pub(crate) fn arm(&mut self, cap: table::Capacity) {
self.slots = Some(cap.into_iter());
}
}
impl State for Frozen {
fn scan(&mut self) -> Option<&mut Scan> {
None
}
fn next(&mut self) -> Option<indices::SlotIndex> {
None
}
fn is_pending(&self) -> bool {
false
}
}
impl State for Scan {
fn scan(&mut self) -> Option<&mut Scan> {
Some(self)
}
fn next(&mut self) -> Option<indices::SlotIndex> {
let slots = self.slots.as_mut()?;
let slot = slots.next();
if slots.len() == 0 {
self.slots = None;
}
slot
}
fn is_pending(&self) -> bool {
self.slots.is_some()
}
}
#[derive(Clone, Copy)]
pub struct Preserve;
impl Policy for Preserve {
type State = Frozen;
const AUTHORITATIVE: bool = false;
}
#[derive(Clone, Copy)]
pub struct Replace;
impl Policy for Replace {
type State = Scan;
const AUTHORITATIVE: bool = true;
}
const _: () = assert!(mem::size_of::<Frozen>() == 0);
const _: () = assert!(mem::size_of::<Scan>() <= 2 * mem::size_of::<usize>());