mod mapper;
use crate::{
dto::canister::CanisterInfo,
ops::{
ic::IcOps,
prelude::*,
runtime::env::EnvOps,
storage::{children::mapper::CanisterRecordMapper, registry::subnet::SubnetRegistryOps},
},
storage::{
canister::{CanisterEntryRecord, CanisterRecord},
stable::children::{CanisterChildren, CanisterChildrenData},
},
};
pub struct CanisterChildrenOps;
impl CanisterChildrenOps {
#[must_use]
pub fn get(pid: Principal) -> Option<CanisterRecord> {
if EnvOps::is_root() {
SubnetRegistryOps::get(pid)
} else {
CanisterChildren::get(pid)
}
}
#[must_use]
pub fn role_parent(pid: Principal) -> Option<(CanisterRole, Option<Principal>)> {
Self::get(pid).map(|record| (record.role, record.parent_pid))
}
#[must_use]
pub fn contains_pid(pid: &Principal) -> bool {
if EnvOps::is_root() {
SubnetRegistryOps::children(IcOps::canister_self())
.iter()
.any(|entry| &entry.pid == pid)
} else {
Self::data().entries.iter().any(|entry| &entry.pid == pid)
}
}
#[must_use]
pub fn infos() -> Vec<CanisterInfo> {
Self::records()
.into_iter()
.map(|entry| CanisterRecordMapper::record_to_response(entry.pid, entry.record))
.collect()
}
#[must_use]
fn records() -> Vec<CanisterEntryRecord> {
if EnvOps::is_root() {
SubnetRegistryOps::children(IcOps::canister_self())
} else {
Self::data().entries
}
}
#[must_use]
pub fn pids() -> Vec<Principal> {
Self::records().into_iter().map(|entry| entry.pid).collect()
}
#[must_use]
pub fn data() -> CanisterChildrenData {
CanisterChildren::export()
}
pub(crate) fn import_direct_children(
parent_pid: Principal,
children: Vec<(Principal, CanisterRole)>,
) {
let data = CanisterChildrenData {
entries: children
.into_iter()
.map(|(pid, role)| CanisterEntryRecord {
pid,
record: CanisterRecord {
role,
parent_pid: Some(parent_pid),
module_hash: None,
created_at: 0,
},
})
.collect(),
};
CanisterChildren::import(data);
}
}