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 fn new() -> Self {
39 Self::default()
40 }
41
42 #[must_use]
43 pub fn get(ty: &CanisterRole) -> Option<WasmModule> {
44 WASM_REGISTRY.with_borrow(|reg| reg.get(ty).cloned())
45 }
46
47 pub fn try_get(ty: &CanisterRole) -> Result<WasmModule, Error> {
48 Self::get(ty).ok_or_else(|| WasmRegistryError::WasmNotFound(ty.clone()).into())
49 }
50
51 #[allow(clippy::cast_precision_loss)]
52 pub fn insert(canister_type: &CanisterRole, wasm: WasmModule) {
53 let wasm_size = wasm.len();
54
55 WASM_REGISTRY.with_borrow_mut(|reg| {
56 reg.insert(canister_type.clone(), wasm);
57 });
58
59 log!(
60 Topic::Wasm,
61 Info,
62 "📄 registry.insert: {} ({:.2} KB)",
63 canister_type,
64 wasm_size as f64 / 1000.0
65 );
66 }
67
68 pub fn import(wasms: &'static [(CanisterRole, &[u8])]) {
69 for (ty, bytes) in wasms {
70 Self::insert(ty, WasmModule::new(bytes));
71 }
72 }
73}