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}