canic_core/model/memory/
env.rs1use crate::{
2 cdk::{
3 api::canister_self,
4 structures::{DefaultMemoryImpl, cell::Cell, memory::VirtualMemory},
5 },
6 eager_static, ic_memory,
7 ids::{CanisterRole, SubnetRole},
8 memory::impl_storable_bounded,
9 model::memory::id::ENV_ID,
10};
11use candid::{CandidType, Principal};
12use serde::{Deserialize, Serialize};
13use std::cell::RefCell;
14
15eager_static! {
21 static ENV: RefCell<Cell<EnvData, VirtualMemory<DefaultMemoryImpl>>> =
22 RefCell::new(Cell::init(
23 ic_memory!(EnvData, ENV_ID),
24 EnvData::default(),
25 ));
26}
27
28#[derive(CandidType, Clone, Debug, Default, Deserialize, Serialize)]
40pub struct EnvData {
41 pub prime_root_pid: Option<Principal>,
43
44 pub subnet_role: Option<SubnetRole>,
46 pub subnet_pid: Option<Principal>,
47 pub root_pid: Option<Principal>,
48
49 pub canister_role: Option<CanisterRole>,
51 pub parent_pid: Option<Principal>,
52}
53
54impl_storable_bounded!(EnvData, 256, true);
55
56pub struct Env;
61
62impl Env {
63 #[must_use]
68 pub(crate) fn get_prime_root_pid() -> Option<Principal> {
69 ENV.with_borrow(|cell| cell.get().prime_root_pid)
70 }
71
72 pub(crate) fn set_prime_root_pid(pid: Principal) {
73 ENV.with_borrow_mut(|cell| {
74 let mut data = cell.get().clone();
75 data.prime_root_pid = Some(pid);
76 cell.set(data);
77 });
78 }
79
80 #[must_use]
81 pub(crate) fn is_prime_root() -> bool {
82 let prime_root_pid = Self::get_prime_root_pid();
83
84 prime_root_pid.is_some() && prime_root_pid == Self::get_root_pid()
85 }
86
87 #[must_use]
92 pub(crate) fn get_subnet_role() -> Option<SubnetRole> {
93 ENV.with_borrow(|cell| cell.get().subnet_role.clone())
94 }
95
96 pub(crate) fn set_subnet_role(role: SubnetRole) {
97 ENV.with_borrow_mut(|cell| {
98 let mut data = cell.get().clone();
99 data.subnet_role = Some(role);
100 cell.set(data);
101 });
102 }
103
104 #[must_use]
105 pub(crate) fn is_prime_subnet() -> bool {
106 Self::get_subnet_role().is_some_and(|r| r.is_prime())
107 }
108
109 #[must_use]
114 pub(crate) fn get_subnet_pid() -> Option<Principal> {
115 ENV.with_borrow(|cell| cell.get().subnet_pid)
116 }
117
118 pub(crate) fn set_subnet_pid(pid: Principal) {
119 ENV.with_borrow_mut(|cell| {
120 let mut data = cell.get().clone();
121 data.subnet_pid = Some(pid);
122 cell.set(data);
123 });
124 }
125
126 #[must_use]
131 pub(crate) fn get_root_pid() -> Option<Principal> {
132 ENV.with_borrow(|cell| cell.get().root_pid)
133 }
134
135 pub(crate) fn set_root_pid(pid: Principal) {
136 ENV.with_borrow_mut(|cell| {
137 let mut data = cell.get().clone();
138 data.root_pid = Some(pid);
139 cell.set(data);
140 });
141 }
142
143 #[must_use]
144 pub(crate) fn is_root() -> bool {
145 Self::get_root_pid() == Some(canister_self())
146 }
147
148 #[must_use]
153 pub(crate) fn get_canister_role() -> Option<CanisterRole> {
154 ENV.with_borrow(|cell| cell.get().canister_role.clone())
155 }
156
157 pub(crate) fn set_canister_role(role: CanisterRole) {
159 ENV.with_borrow_mut(|cell| {
160 let mut data = cell.get().clone();
161 data.canister_role = Some(role);
162 cell.set(data);
163 });
164 }
165
166 #[must_use]
171 pub(crate) fn get_parent_pid() -> Option<Principal> {
172 ENV.with_borrow(|cell| cell.get().parent_pid)
173 }
174
175 pub(crate) fn import(data: EnvData) {
181 ENV.with_borrow_mut(|cell| {
182 cell.set(data);
183 });
184 }
185
186 #[must_use]
187 pub(crate) fn export() -> EnvData {
188 ENV.with_borrow(|cell| cell.get().clone())
189 }
190}