canic_core/model/wasm/
wasm_registry.rs1use crate::{Error, ids::CanisterRole, log, log::Topic, model::ModelError, types::WasmModule};
2use std::{cell::RefCell, collections::HashMap};
3use thiserror::Error as ThisError;
4
5thread_local! {
10 pub static WASM_REGISTRY: RefCell<HashMap<CanisterRole, WasmModule>> = RefCell::new(HashMap::new());
11}
12
13#[derive(Debug, ThisError)]
18pub enum WasmRegistryError {
19 #[error("wasm '{0}' not found")]
20 WasmNotFound(CanisterRole),
21}
22
23impl From<WasmRegistryError> for Error {
24 fn from(err: WasmRegistryError) -> Self {
25 ModelError::from(err).into()
26 }
27}
28
29#[derive(Debug, Default)]
34pub struct WasmRegistry {}
35
36impl WasmRegistry {
37 #[must_use]
38 pub(crate) fn get(ty: &CanisterRole) -> Option<WasmModule> {
39 WASM_REGISTRY.with_borrow(|reg| reg.get(ty).cloned())
40 }
41
42 pub(crate) fn try_get(ty: &CanisterRole) -> Result<WasmModule, Error> {
43 Self::get(ty).ok_or_else(|| WasmRegistryError::WasmNotFound(ty.clone()).into())
44 }
45
46 #[allow(clippy::cast_precision_loss)]
47 pub(crate) fn insert(canister_type: &CanisterRole, wasm: WasmModule) {
48 let wasm_size = wasm.len();
49
50 WASM_REGISTRY.with_borrow_mut(|reg| {
51 reg.insert(canister_type.clone(), wasm);
52 });
53
54 log!(
55 Topic::Wasm,
56 Info,
57 "📄 registry.insert: {} ({:.2} KB)",
58 canister_type,
59 wasm_size as f64 / 1000.0
60 );
61 }
62
63 pub(crate) fn import(wasms: &'static [(CanisterRole, &[u8])]) {
64 for (ty, bytes) in wasms {
65 Self::insert(ty, WasmModule::new(bytes));
66 }
67 }
68}