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
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use super::{Actor, AknShutdown, LauncherSender, Passthrough, Shutdown, Starter};
use serde::{Deserialize, Serialize};
use std::fmt::Display;

/// Allows an actor to be built by parts
pub trait Builder {
    /// The "state" (actor type) which is built
    type State;
    /// Build the actor
    fn build(self) -> Self::State;
}

/// Should be implemented on the ActorBuilder struct
pub trait ActorBuilder<H: AknShutdown<Self::State> + 'static>: Builder
where
    Self::State: Actor<H>,
{
}

/// Should be implemented on the AppBuilder struct
pub trait AppBuilder<H: LauncherSender<Self> + AknShutdown<Self::State>>: Builder + ThroughType + Clone + Starter<H>
where
    Self::State: Actor<H>,
    Self::Ok: Shutdown + Passthrough<Self::Through>,
    Self::Input: From<Self::State>,
    Self::Error: Display,
{
}

pub trait ThroughType {
    /// identfiy the Through which is the event type with predefind functionality to the outdoor (ie websocket msg)
    type Through: for<'de> Deserialize<'de> + Serialize;
}

/// Create the builder type for an actor, which can be used to construct an actor by parts
#[macro_export]
macro_rules! builder {
    ( $(#[derive($($der:tt),*)])?  $struct:ident {$( $field:ident: $type:tt$(<$($i:tt),*>)? ),*} ) => {
        #[allow(missing_docs)]
        #[derive($($($der,)*)?Default)]
        pub struct $struct {
            $(
                $field: Option<$type$(<$($i,)*>)?>,
            )*
        }

        impl $struct {
            /// Create a new $struct
            pub fn new() -> Self {
                Self {
                    $(
                        $field: None,
                    )*
                }
            }

            $(
                /// Set $field on the builder
                pub fn $field(mut self, $field: $type$(<$($i,)*>)?) -> Self {
                    self.$field.replace($field);
                    self
                }
            )*
        }

    };
    ($(#[derive($($der:tt),*)])? $struct:ident$(<$($extra:tt),*>)? {$( $field:ident: $type:tt$(<$($i:tt),*>)? ),*}) => {
        #[derive($($($der,)*)?Default)]
        #[allow(missing_docs)]
        pub struct $struct$(<$($extra,)*>)? {
            $(
                $field: Option<$type$(<$($i,)*>)?>,
            )*
            #[allow(unused_parens)]
            $(
                _phantom: std::marker::PhantomData<$($extra,)*>
            )?
        }

        impl$(<$($extra,)*>)? $struct$(<$($extra,)*>)? {
            /// Create a new $struct
            pub fn new() -> Self {
                Self {
                    $(
                        $field: None,
                    )*
                    _phantom: std::marker::PhantomData,
                }
            }
            $(
                /// Set $field on the builder
                pub fn $field(mut self, $field: $type$(<$($i,)*>)?) -> Self {
                    self.$field.replace($field);
                    self
                }
            )*
        }
    };


}