1use crate::{
17 cdk::types::Cycles,
18 dto::{prelude::*, rpc::RootRequestMetadata},
19};
20
21pub use crate::domain::pool::CanisterPoolStatus;
22
23#[derive(CandidType, Clone, Debug, Deserialize)]
29pub struct CanisterPoolResponse {
30 pub entries: Vec<CanisterPoolEntry>,
31}
32
33#[derive(CandidType, Clone, Debug, Deserialize)]
38pub struct CanisterPoolEntry {
39 pub pid: Principal,
40 pub created_at: u64,
41 pub cycles: Cycles,
42 pub status: CanisterPoolStatus,
43 pub role: Option<CanisterRole>,
44 pub parent: Option<Principal>,
45 pub module_hash: Option<Vec<u8>>,
46}
47
48#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
56pub enum PoolAdminCommand {
57 CreateEmpty(CreateEmptyPoolRequest),
59
60 Recycle { pid: Principal },
62
63 ImportImmediate { pid: Principal },
65
66 ImportQueued { pids: Vec<Principal> },
68}
69
70#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
75pub struct CreateEmptyPoolRequest {
76 #[serde(default)]
77 pub metadata: Option<RootRequestMetadata>,
78}
79
80#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
86pub enum PoolAdminResponse {
87 Created { pid: Principal },
89
90 Recycled,
92
93 Imported,
95
96 QueuedImported { result: PoolBatchResult },
98}
99
100#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
105pub struct PoolBatchResult {
106 pub total: u64,
107 pub added: u64,
108 pub requeued: u64,
109 pub skipped: u64,
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn reexported_pool_status_roundtrips_through_candid() {
118 let entry = CanisterPoolEntry {
119 pid: Principal::from_slice(&[3; 29]),
120 created_at: 42,
121 cycles: Cycles::new(10_000),
122 status: crate::domain::pool::CanisterPoolStatus::Failed {
123 reason: "bounded reset failure".to_string(),
124 },
125 role: Some(CanisterRole::new("worker")),
126 parent: None,
127 module_hash: Some(vec![1, 2, 3]),
128 };
129
130 let bytes = candid::encode_one(&entry).expect("encode pool entry");
131 let decoded: CanisterPoolEntry = candid::decode_one(&bytes).expect("decode pool entry");
132
133 let dto_status: CanisterPoolStatus = crate::domain::pool::CanisterPoolStatus::Failed {
134 reason: "bounded reset failure".to_string(),
135 };
136
137 assert_eq!(decoded.pid, Principal::from_slice(&[3; 29]));
138 assert_eq!(decoded.created_at, 42);
139 assert_eq!(decoded.cycles, Cycles::new(10_000));
140 assert_eq!(decoded.status, dto_status);
141 assert_eq!(decoded.role, Some(CanisterRole::new("worker")));
142 assert_eq!(decoded.parent, None);
143 assert_eq!(decoded.module_hash, Some(vec![1, 2, 3]));
144 }
145}