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 pub metadata: Option<RootRequestMetadata>,
77}
78
79#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
85pub enum PoolAdminResponse {
86 Created { pid: Principal },
88
89 Recycled,
91
92 Imported,
94
95 QueuedImported { result: PoolBatchResult },
97}
98
99#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
104pub struct PoolBatchResult {
105 pub total: u64,
106 pub added: u64,
107 pub requeued: u64,
108 pub skipped: u64,
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn reexported_pool_status_roundtrips_through_candid() {
117 let entry = CanisterPoolEntry {
118 pid: Principal::from_slice(&[3; 29]),
119 created_at: 42,
120 cycles: Cycles::new(10_000),
121 status: crate::domain::pool::CanisterPoolStatus::Failed {
122 reason: "bounded reset failure".to_string(),
123 },
124 role: Some(CanisterRole::new("worker")),
125 parent: None,
126 module_hash: Some(vec![1, 2, 3]),
127 };
128
129 let bytes = candid::encode_one(&entry).expect("encode pool entry");
130 let decoded: CanisterPoolEntry = candid::decode_one(&bytes).expect("decode pool entry");
131
132 let dto_status: CanisterPoolStatus = crate::domain::pool::CanisterPoolStatus::Failed {
133 reason: "bounded reset failure".to_string(),
134 };
135
136 assert_eq!(decoded.pid, Principal::from_slice(&[3; 29]));
137 assert_eq!(decoded.created_at, 42);
138 assert_eq!(decoded.cycles, Cycles::new(10_000));
139 assert_eq!(decoded.status, dto_status);
140 assert_eq!(decoded.role, Some(CanisterRole::new("worker")));
141 assert_eq!(decoded.parent, None);
142 assert_eq!(decoded.module_hash, Some(vec![1, 2, 3]));
143 }
144}