use super::OperationPlanError;
use crate::model::artifacts::canonical_hash;
use crate::model::attempt_journal::OperationBindingRecord;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
pub struct PlanContextRequest {
pub network: String,
pub caller: String,
pub release: String,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(try_from = "ContextFields")]
pub struct PlanContextRecord {
network: String,
caller: String,
release: String,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct ContextFields {
network: String,
caller: String,
release: String,
}
impl TryFrom<ContextFields> for PlanContextRecord {
type Error = OperationPlanError;
fn try_from(fields: ContextFields) -> Result<Self, Self::Error> {
Self::new(&PlanContextRequest {
network: fields.network,
caller: fields.caller,
release: fields.release,
})
}
}
impl PlanContextRecord {
pub(crate) fn binding_mismatch(
&self,
binding: &OperationBindingRecord,
) -> Option<&'static str> {
if self.network() != binding.network() {
Some("network")
} else if self.caller() != binding.caller() {
Some("caller")
} else if self.release() != binding.release() {
Some("release")
} else {
None
}
}
pub fn new(request: &PlanContextRequest) -> Result<Self, OperationPlanError> {
Ok(Self {
network: canonical_hash(&request.network)?,
caller: crate::model::principal::canonical_text(&request.caller)
.ok_or(OperationPlanError::InvalidPrincipal("caller"))?,
release: canonical_hash(&request.release)?,
})
}
#[must_use]
pub fn network(&self) -> &str {
&self.network
}
#[must_use]
pub fn caller(&self) -> &str {
&self.caller
}
#[must_use]
pub fn release(&self) -> &str {
&self.release
}
}