ori_app/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#![deny(missing_docs)]
#![allow(clippy::module_inception)]

//! An application interface for the Ori library.

mod app;
mod builder;
mod command;
mod delegate;
mod request;

pub use app::*;
pub use builder::*;
pub use command::*;
pub use delegate::*;
pub use request::*;

use ori_core::view::{AnyView, BoxedView};

/// A builder for a user interface.
pub type UiBuilder<T> = Box<dyn FnMut(&mut T) -> BoxedView<T>>;

/// Trait for converting a type into a [`UiBuilder`].
pub trait IntoUiBuilder<V, P> {
    /// The data type of the returned view.
    type Data;

    /// Convert a type into it's requisite [`UiBuilder`].
    fn into_ui_builder(self) -> UiBuilder<Self::Data>;
}

impl<T, V, F> IntoUiBuilder<V, &mut T> for F
where
    F: FnMut(&mut T) -> V + 'static,
    V: AnyView<T> + 'static,
{
    type Data = T;

    fn into_ui_builder(mut self) -> UiBuilder<Self::Data> {
        Box::new(move |data| Box::new(self(data)))
    }
}

impl<T, V, F> IntoUiBuilder<V, (T,)> for F
where
    F: FnMut() -> V + 'static,
    V: AnyView<T> + 'static,
{
    type Data = T;

    fn into_ui_builder(mut self) -> UiBuilder<Self::Data> {
        Box::new(move |_| Box::new(self()))
    }
}