ic_backup/model/operation_plan/budget/
mod.rs1use super::OperationPlanError;
4use serde::{Deserialize, Serialize};
5
6pub const MAX_PLAN_ATTEMPTS: u32 = 65536;
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
10#[serde(try_from = "BudgetFields")]
11pub struct PlanBudgetRecord {
12 mutations: u32,
13 observations: u32,
14}
15#[derive(Deserialize)]
16#[serde(deny_unknown_fields)]
17struct BudgetFields {
18 mutations: u32,
19 observations: u32,
20}
21impl TryFrom<BudgetFields> for PlanBudgetRecord {
22 type Error = OperationPlanError;
23 fn try_from(fields: BudgetFields) -> Result<Self, Self::Error> {
24 Self::new(fields.mutations, fields.observations)
25 }
26}
27impl PlanBudgetRecord {
28 pub fn new(mutations: u32, observations: u32) -> Result<Self, OperationPlanError> {
33 if mutations
34 .checked_add(observations)
35 .is_none_or(|total| total > MAX_PLAN_ATTEMPTS)
36 {
37 return Err(OperationPlanError::BudgetTooLarge);
38 }
39 Ok(Self {
40 mutations,
41 observations,
42 })
43 }
44 #[must_use]
46 pub const fn mutations(&self) -> u32 {
47 self.mutations
48 }
49 #[must_use]
51 pub const fn observations(&self) -> u32 {
52 self.observations
53 }
54 pub(super) const fn admits(&self, allocated: AllocatedAttemptsView) -> bool {
55 allocated.mutations <= self.mutations && allocated.observations <= self.observations
56 }
57}
58#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
60pub struct AllocatedAttemptsView {
61 pub mutations: u32,
63 pub observations: u32,
65}