selium-kernel 1.0.0-alpha.6

Streaming compute fabric
Documentation
use std::{
    any::{Any, TypeId},
    collections::HashMap,
    num::TryFromIntError,
    sync::Arc,
};

use thiserror::Error;

use crate::registry::RegistryError;

pub mod drivers;
pub mod futures;
pub mod guest_async;
pub mod guest_data;
pub mod mailbox;
pub mod operation;
pub mod registry;
pub mod session;

pub struct Kernel {
    capabilities: HashMap<TypeId, Arc<dyn Any>>,
}

#[derive(Default)]
pub struct KernelBuilder {
    capabilities: HashMap<TypeId, Arc<dyn Any>>,
}

#[derive(Error, Debug)]
pub enum KernelError {
    #[error("Linker error")]
    LinkerError(#[from] wasmtime::Error),
    #[error("Could not access guest memory")]
    MemoryAccess(#[from] wasmtime::MemoryAccessError),
    #[error("Guest did not reserve enough memory for this call")]
    MemoryCapacity,
    #[error("Could not retrieve guest memory from `Caller`")]
    MemoryMissing,
    #[error("Could not convert int to usize")]
    IntConvert(#[from] TryFromIntError),
    #[error("Invalid resource handle provided by guest")]
    InvalidHandle,
    #[error("Registry error")]
    Registry(#[from] RegistryError),
    #[error("Driver error: {0}")]
    Driver(String),
}

impl Kernel {
    pub fn build() -> KernelBuilder {
        KernelBuilder::default()
    }

    pub fn get<C: 'static>(&self) -> Option<&C> {
        self.capabilities
            .get(&TypeId::of::<C>())
            .and_then(|cap| cap.downcast_ref::<C>())
    }
}

impl KernelBuilder {
    pub fn add_capability<C: 'static>(&mut self, capability: Arc<C>) -> Arc<C> {
        self.capabilities
            .insert(TypeId::of::<C>(), capability.clone());
        capability
    }

    pub fn build(self) -> Result<Kernel, KernelError> {
        Ok(Kernel {
            capabilities: self.capabilities,
        })
    }
}