use super::Ream;
use crate::env::*;
use crate::{Setup, Sketch};
#[cfg_attr(docsrs, doc(cfg(feature = "ream-single")))]
pub struct Single<S, I = ()> {
inner: SingleInner<S, I>,
}
impl<E> core::fmt::Debug for Single<E> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Single").finish()
}
}
enum SingleInner<S, I> {
Sketch(S),
Input(I),
Temp,
}
impl<S, I> SingleInner<S, I> {
fn take_input(&mut self) -> I {
use SingleInner::*;
match core::mem::replace(self, Temp) {
Input(input) => input,
_ => panic!("Attempted to take input from non-input variant."),
}
}
}
impl<S, I> Single<S, I> {
pub fn new() -> Self
where
I: Default,
{
Self {
inner: SingleInner::Input(I::default()),
}
}
pub fn with_input(input: I) -> Self {
Self {
inner: SingleInner::Input(input),
}
}
}
impl<S, I> Default for Single<S, I>
where
I: Default,
{
fn default() -> Self {
Self::new()
}
}
impl<S, I> From<I> for Single<S, I> {
fn from(input: I) -> Self {
Self::with_input(input)
}
}
impl<S, I> Ream for Single<S, I>
where
S: Sketch + Setup<I>,
{
type Env = S::Env;
type Error = core::convert::Infallible;
fn update(&mut self, mill: &mut MillOf<Self::Env>) -> Result<Status, Self::Error> {
use SingleInner::*;
match &mut self.inner {
inner @ Input(_) => {
let page = mill.new_page();
self.inner = Sketch(S::setup(page, inner.take_input()));
Ok(Status::Continue)
}
Sketch(sketch) => {
sketch.get_page_mut().start_group();
while let Some(event) = sketch.get_page_mut().next_event_in_group() {
sketch.get_page_mut().before_event(&event);
sketch.handle_environment_event(&event);
sketch.get_page_mut().finish_event(event);
}
sketch.get_page_mut().end_group();
Ok(sketch.get_page_mut().status())
}
Temp => unreachable!(),
}
}
}