Skip to main content

selium_kernel/
lib.rs

1use std::{
2    any::{Any, TypeId},
3    collections::HashMap,
4    num::TryFromIntError,
5    sync::Arc,
6};
7
8use thiserror::Error;
9
10use crate::registry::RegistryError;
11
12pub mod drivers;
13pub mod futures;
14pub mod guest_async;
15pub mod guest_data;
16pub mod mailbox;
17pub mod operation;
18pub mod registry;
19pub mod session;
20
21pub struct Kernel {
22    capabilities: HashMap<TypeId, Arc<dyn Any>>,
23}
24
25#[derive(Default)]
26pub struct KernelBuilder {
27    capabilities: HashMap<TypeId, Arc<dyn Any>>,
28}
29
30#[derive(Error, Debug)]
31pub enum KernelError {
32    #[error("Linker error")]
33    LinkerError(#[from] wasmtime::Error),
34    #[error("Could not access guest memory")]
35    MemoryAccess(#[from] wasmtime::MemoryAccessError),
36    #[error("Guest did not reserve enough memory for this call")]
37    MemoryCapacity,
38    #[error("Could not retrieve guest memory from `Caller`")]
39    MemoryMissing,
40    #[error("Could not convert int to usize")]
41    IntConvert(#[from] TryFromIntError),
42    #[error("Invalid resource handle provided by guest")]
43    InvalidHandle,
44    #[error("Registry error")]
45    Registry(#[from] RegistryError),
46    #[error("Driver error: {0}")]
47    Driver(String),
48}
49
50impl Kernel {
51    pub fn build() -> KernelBuilder {
52        KernelBuilder::default()
53    }
54
55    pub fn get<C: 'static>(&self) -> Option<&C> {
56        self.capabilities
57            .get(&TypeId::of::<C>())
58            .and_then(|cap| cap.downcast_ref::<C>())
59    }
60}
61
62impl KernelBuilder {
63    pub fn add_capability<C: 'static>(&mut self, capability: Arc<C>) -> Arc<C> {
64        self.capabilities
65            .insert(TypeId::of::<C>(), capability.clone());
66        capability
67    }
68
69    pub fn build(self) -> Result<Kernel, KernelError> {
70        Ok(Kernel {
71            capabilities: self.capabilities,
72        })
73    }
74}