#![cfg_attr(
docsrs,
cfg_attr(doc, doc = ::document_features::document_features!())
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(
bad_style,
const_err,
dead_code,
improper_ctypes,
non_shorthand_field_patterns,
no_mangle_generic_items,
overflowing_literals,
path_statements,
patterns_in_fns_without_body,
private_in_public,
unconditional_recursion,
unused,
unused_allocation,
unused_comparisons,
unused_parens,
while_true
)]
#![warn(
rust_2018_idioms,
missing_debug_implementations,
missing_docs,
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_import_braces,
unused_qualifications,
unused_results,
unsafe_code
)]
#![deny(clippy::unwrap_used, clippy::expect_used)]
#[cfg(feature = "alloc")]
extern crate alloc;
pub mod compose;
mod env;
pub mod ream;
mod book;
mod real;
pub mod aspects;
mod geometry;
pub use book::*;
pub use env::*;
pub use geometry::*;
pub use real::*;
pub trait Sketch {
type Env: Environment;
fn get_page(&self) -> &PageOf<Self::Env>;
fn get_page_mut(&mut self) -> &mut PageOf<Self::Env>;
fn handle_environment_event(&mut self, event: &EventOf<Self::Env>);
}
impl<C, S> compose::AsPart<C> for S
where
S: Sketch,
PageOf<S::Env>: compose::AsPart<C>,
{
fn as_part(&self) -> &C {
self.get_page().as_part()
}
fn as_part_mut(&mut self) -> &mut C {
self.get_page_mut().as_part_mut()
}
}
pub trait Setup<Input = ()>
where
Self: Sketch,
{
fn setup(page: PageOf<Self::Env>, input: Input) -> Self;
}
#[macro_export]
macro_rules! derive_sketch {
{
$(#[doc = $docs:literal])?
#[sketch(env = $env_name:ident $(, aspects = ($($aspect_name:ident),* $(,)?))? $(,)?)]
$struct_vis:vis
struct $sketch_name:ident {
$($($before_vis:vis $before_field_name:ident : $before_field_type:ty),+,)?
#[page] $page_vis:vis $page_name:ident: $page_type:ty
$(,$($after_vis:vis $after_field_name:ident : $after_field_type:ty),+)?$(,)?
}
} => {
$(#[doc = $docs])?
$struct_vis
struct $sketch_name {
$($($before_vis $before_field_name : $before_field_type),+,)?
$page_vis $page_name: $page_type
$(,$($after_vis $after_field_name : $after_field_type),+)?
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl $crate::Sketch for $sketch_name {
type Env = $env_name::Env;
fn get_page(&self) -> &$crate::PageOf<$env_name::Env> {
&self.$page_name
}
fn get_page_mut(&mut self) -> &mut $crate::PageOf<$env_name::Env> {
&mut self.$page_name
}
fn handle_environment_event(
&mut self,
event: &$crate::EventOf<Self::Env>,
) {
use $crate::compose::TryAsPart;
$($(
if let Some(event) = event.try_as_part() {
<Self as $aspect_name::RunHandlers>::run_handlers(self, event);
}
)*)?
}
}
$($(
#[automatically_derived]
#[allow(unused_qualifications)]
impl $aspect_name::RunHandlers for $sketch_name {}
)*)?
};
{
$(#[doc = $docs:literal])?
#[sketch(env = $env_name:ident $(, aspects = ($($aspect_name:ident),* $(,)?))? $(,)?)]
$struct_vis:vis
struct $sketch_name:ident {
$($code:tt)*
}
} => {
compile_error!("Missing `#[page]` attribute on field for environment's page.");
};
{
$(#[doc = $docs:literal])?
$(#[sketch($($attr:tt)*)])?
$struct_vis:vis
struct $sketch_name:ident {
$($code:tt)*
}
} => {
compile_error!("Missing `#[sketch(env = .., aspects = (.., ...))]` attribute.");
};
{
$($tokens:tt)*
} => {
compile_error!("Unable to parse struct. See docs for `derive_sketch!` for expected syntax.");
}
}
#[cfg(feature = "derive")]
pub use macro_rules_attribute::apply;