nucleon 0.1.1

Building blocks to create a Nucleus app.
Documentation
use async_std::channel::Sender;

use nucleus_rpc::prelude::*;
use nucleus_rpc::Message;

/// This macro registers all the required functions and data to export the Nucleon.
/// This makes sure the env logger is inited, the static info is exposed and a constructor is present.
/// Also a helper `NUCLEON_TYPE` is made available to use inside the Nucleon implementation.
#[macro_export]
macro_rules! register_nucleon {
    ($plugin_type:ty) => {
        static NUCLEON_TYPE: &str = stringify!($plugin_type);

        #[no_mangle]
        pub fn init() {
            env_logger::init();
        }

        #[no_mangle]
        pub fn new(config: &NucleonConfig, tx: &Sender<Message>) -> *mut Nucleon {
            let boxed = Box::new(<$plugin_type>::new(config.clone(), tx.clone()));
            Box::into_raw(boxed)
        }

        #[no_mangle]
        pub fn static_info() -> NucleonInfo {
            <$plugin_type>::static_info()
        }
    };
}

/// Helper function to make adding a property easier.
#[inline]
pub fn property<T>(
    name: &str,
    display_name: &str,
    description: &str,
    default_value: T,
) -> PropertyDescription
where
    Value: From<T>,
{
    PropertyDescription {
        name: name.to_string(),
        display_name: display_name.to_string(),
        description: description.to_string(),
        default_value: default_value.into(),
    }
}

/// The Nucleon prelude
pub mod prelude {
    pub use super::register_nucleon;

    pub use nucleus_rpc::prelude::*;

    pub use super::{property, Nucleon, NucleonStatic};
    pub use async_std::channel::Sender;

    pub type NucleonInner<T> = std::sync::Arc<async_std::sync::Mutex<T>>;

    pub fn nvr_inner_new<T>(inner: T) -> NucleonInner<T> {
        std::sync::Arc::new(async_std::sync::Mutex::new(inner))
    }
}

/// Exports used for a framework builder (Nucleus)
pub mod exports {
    pub use super::prelude::*;
    pub use async_std::channel::Receiver;

    pub type NucleonStaticInfo = fn() -> NucleonInfo;
    pub type NucleonCreate = fn(&NucleonConfig, &Sender<Message>) -> *mut dyn Nucleon;
    pub type NucleonInit = fn();
}

/// Trait required to expose the Nucleon static information.
pub trait NucleonStatic: Send + Sync {
    fn new(config: NucleonConfig, tx: Sender<Message>) -> Self;

    fn static_info() -> NucleonInfo;
}

/// Trait required to expose the Nucleon instance functions
pub trait Nucleon: Send + Sync {
    fn init(&mut self);

    fn start(&mut self);
    fn stop(&mut self);

    fn update(&self, properties: &Properties);

    fn get_name(&self) -> &str;
    fn get_config(&self) -> NucleonConfig;

    fn on_message(&self, message: Message);
}