sketchbook 0.0.2

Interactive visual applications in Rust
Documentation
use core::marker::PhantomData;

use crate::env::*;
use crate::ream::*;

/// A set of sketches.
///
/// This struct doesn't provide any new functionallity; It just allows a nicer to read API for the
/// user.
#[derive(Debug)]
pub struct Book<R> {
    phantom_data: PhantomData<R>,
}

/// Pages of a book.
///
/// This exists for reams to add functionallity to it.
pub struct Pages<R>
where
    R: Ream,
{
    /// The ream for the pages.
    pub ream: R,

    /// The environment the pages are in.
    pub env: <R as Ream>::Env,
}

impl<R> core::fmt::Debug for Pages<R>
where
    R: Ream + core::fmt::Debug,
    <R as Ream>::Env: core::fmt::Debug,
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("Pages")
            .field("ream", &self.ream)
            .field("env", &self.env)
            .finish()
    }
}

impl<R> Pages<R>
where
    R: Ream + 'static,
{
    /// Bind into a book.
    ///
    /// This runs the ream and all sketches it contains.
    ///
    /// Returns what the environment returns.
    pub fn bind(self) -> <<R as Ream>::Env as Environment>::Return {
        let mut ream = self.ream;
        self.env.run(move |proxy| ream.update(proxy))
    }
}

impl<R> Book<R>
where
    R: Default + Ream + 'static,
    <R as Ream>::Env: Default,
{
    /// Create pages to add sketches to.
    pub fn pages() -> Pages<R> {
        Pages {
            ream: R::default(),
            env: <R as Ream>::Env::default(),
        }
    }

    /// Immediately bind a new book.
    ///
    /// This will start running the ream and therefore any sketches.
    pub fn bind() -> <<R as Ream>::Env as Environment>::Return {
        Self::pages().bind()
    }
}

impl<R> Book<R>
where
    R: Ream,
    <R as Ream>::Env: Default,
{
    /// Create pages with input data.
    pub fn pages_with<I>(input: I) -> Pages<R>
    where
        R: From<I>,
    {
        Pages {
            ream: R::from(input),
            env: <R as Ream>::Env::default(),
        }
    }

    /// Bind the book with some input value.
    pub fn bind_with<I>(input: I) -> <<R as Ream>::Env as Environment>::Return
    where
        R: From<I> + 'static,
    {
        Self::pages_with(input).bind()
    }
}