canic/memory/context/
subnet.rs1use crate::{
2 Error,
3 cdk::structures::{DefaultMemoryImpl, cell::Cell, memory::VirtualMemory},
4 eager_static, ic_memory, impl_storable_bounded,
5 memory::{MemoryError, context::ContextError, id::context::SUBNET_CONTEXT_ID},
6};
7use candid::{CandidType, Principal};
8use serde::{Deserialize, Serialize};
9use std::cell::RefCell;
10use thiserror::Error as ThisError;
11
12eager_static! {
17 static SUBNET_CONTEXT: RefCell<Cell<SubnetContextData, VirtualMemory<DefaultMemoryImpl>>> =
18 RefCell::new(Cell::init(
19 ic_memory!(SubnetState, SUBNET_CONTEXT_ID),
20 SubnetContextData::default(),
21 ));
22}
23
24#[derive(Debug, ThisError)]
29pub enum SubnetContextError {
30 #[error("prime subnet pid has not been set")]
31 PrimeSubnetNotSet,
32
33 #[error("subnet pid has not been set")]
34 SubnetNotSet,
35}
36
37impl From<SubnetContextError> for Error {
38 fn from(err: SubnetContextError) -> Self {
39 MemoryError::from(ContextError::from(err)).into()
40 }
41}
42
43#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
48pub struct SubnetContextData {
49 pub prime_subnet_pid: Option<Principal>,
50 pub subnet_pid: Option<Principal>,
51}
52
53impl_storable_bounded!(SubnetContextData, 64, true);
54
55pub struct SubnetContext;
60
61impl SubnetContext {
62 #[must_use]
64 pub fn get_subnet_pid() -> Option<Principal> {
65 SUBNET_CONTEXT.with_borrow(|cell| cell.get().subnet_pid)
66 }
67
68 pub fn try_get_subnet_pid() -> Result<Principal, Error> {
69 Self::get_subnet_pid().ok_or_else(|| SubnetContextError::SubnetNotSet.into())
70 }
71
72 pub fn set_subnet_pid(pid: Principal) {
73 SUBNET_CONTEXT.with_borrow_mut(|cell| {
74 let mut data = *cell.get();
75 data.subnet_pid = Some(pid);
76 cell.set(data);
77 });
78 }
79
80 #[must_use]
82 pub fn get_prime_subnet_pid() -> Option<Principal> {
83 SUBNET_CONTEXT.with_borrow(|cell| cell.get().prime_subnet_pid)
84 }
85
86 pub fn try_get_prime_subnet_pid() -> Result<Principal, Error> {
87 Self::get_prime_subnet_pid().ok_or_else(|| SubnetContextError::PrimeSubnetNotSet.into())
88 }
89
90 pub fn set_prime_subnet_pid(pid: Principal) {
91 SUBNET_CONTEXT.with_borrow_mut(|cell| {
92 let mut data = *cell.get();
93 data.prime_subnet_pid = Some(pid);
94 cell.set(data);
95 });
96 }
97
98 #[must_use]
101 pub fn export() -> SubnetContextData {
102 SUBNET_CONTEXT.with_borrow(|cell| *cell.get())
103 }
104}