use std::any::Any;
use async_trait::async_trait;
use bee_storage::backend::StorageBackend;
use futures::{channel::oneshot, future::Future};
use crate::{event::Bus, resource::ResourceHandle, worker::Worker};
pub struct NodeInfo {
pub name: String,
pub version: String,
}
#[async_trait]
pub trait Node: Send + Sized + 'static {
type Builder: NodeBuilder<Self>;
type Backend: StorageBackend;
type Error: std::error::Error;
async fn stop(mut self) -> Result<(), Self::Error>;
fn spawn<W, G, F>(&mut self, g: G)
where
W: Worker<Self>,
G: FnOnce(oneshot::Receiver<()>) -> F,
F: Future<Output = ()> + Send + 'static;
fn worker<W>(&self) -> Option<&W>
where
W: Worker<Self> + Send + Sync;
fn register_resource<R: Any + Send + Sync>(&mut self, res: R);
fn remove_resource<R: Any + Send + Sync>(&mut self) -> Option<R>;
#[track_caller]
fn resource<R: Any + Send + Sync>(&self) -> ResourceHandle<R>;
#[track_caller]
fn info(&self) -> ResourceHandle<NodeInfo> {
self.resource()
}
#[track_caller]
fn storage(&self) -> ResourceHandle<Self::Backend> {
self.resource()
}
#[track_caller]
fn bus(&self) -> ResourceHandle<Bus<'static>> {
self.resource()
}
}
#[async_trait(?Send)]
pub trait NodeBuilder<N: Node>: Sized {
type Error: std::error::Error;
type Config;
fn new(config: Self::Config) -> Result<Self, Self::Error>;
#[must_use]
fn with_worker<W: Worker<N> + 'static>(self) -> Self
where
W::Config: Default;
#[must_use]
fn with_worker_cfg<W: Worker<N> + 'static>(self, config: W::Config) -> Self;
#[must_use]
fn with_resource<R: Any + Send + Sync>(self, res: R) -> Self;
async fn finish(self) -> Result<N, Self::Error>;
}