use super::OperationPlanError;
use serde::{Deserialize, Serialize};
pub const MAX_PLAN_ATTEMPTS: u32 = 65536;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(try_from = "BudgetFields")]
pub struct PlanBudgetRecord {
mutations: u32,
observations: u32,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct BudgetFields {
mutations: u32,
observations: u32,
}
impl TryFrom<BudgetFields> for PlanBudgetRecord {
type Error = OperationPlanError;
fn try_from(fields: BudgetFields) -> Result<Self, Self::Error> {
Self::new(fields.mutations, fields.observations)
}
}
impl PlanBudgetRecord {
pub fn new(mutations: u32, observations: u32) -> Result<Self, OperationPlanError> {
if mutations
.checked_add(observations)
.is_none_or(|total| total > MAX_PLAN_ATTEMPTS)
{
return Err(OperationPlanError::BudgetTooLarge);
}
Ok(Self {
mutations,
observations,
})
}
#[must_use]
pub const fn mutations(&self) -> u32 {
self.mutations
}
#[must_use]
pub const fn observations(&self) -> u32 {
self.observations
}
pub(super) const fn admits(&self, allocated: AllocatedAttemptsView) -> bool {
allocated.mutations <= self.mutations && allocated.observations <= self.observations
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
pub struct AllocatedAttemptsView {
pub mutations: u32,
pub observations: u32,
}