ic_backup/model/operation_plan/context/
mod.rs1use super::OperationPlanError;
4use crate::model::artifacts::canonical_hash;
5use crate::model::attempt_journal::OperationBindingRecord;
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug)]
10pub struct PlanContextRequest {
11 pub network: String,
13 pub caller: String,
15 pub release: String,
17}
18#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
20#[serde(try_from = "ContextFields")]
21pub struct PlanContextRecord {
22 network: String,
23 caller: String,
24 release: String,
25}
26#[derive(Deserialize)]
27#[serde(deny_unknown_fields)]
28struct ContextFields {
29 network: String,
30 caller: String,
31 release: String,
32}
33impl TryFrom<ContextFields> for PlanContextRecord {
34 type Error = OperationPlanError;
35 fn try_from(fields: ContextFields) -> Result<Self, Self::Error> {
36 Self::new(&PlanContextRequest {
37 network: fields.network,
38 caller: fields.caller,
39 release: fields.release,
40 })
41 }
42}
43impl PlanContextRecord {
44 pub(crate) fn binding_mismatch(
47 &self,
48 binding: &OperationBindingRecord,
49 ) -> Option<&'static str> {
50 if self.network() != binding.network() {
51 Some("network")
52 } else if self.caller() != binding.caller() {
53 Some("caller")
54 } else if self.release() != binding.release() {
55 Some("release")
56 } else {
57 None
58 }
59 }
60 pub fn new(request: &PlanContextRequest) -> Result<Self, OperationPlanError> {
65 Ok(Self {
66 network: canonical_hash(&request.network)?,
67 caller: crate::model::principal::canonical_text(&request.caller)
68 .ok_or(OperationPlanError::InvalidPrincipal("caller"))?,
69 release: canonical_hash(&request.release)?,
70 })
71 }
72 #[must_use]
74 pub fn network(&self) -> &str {
75 &self.network
76 }
77 #[must_use]
79 pub fn caller(&self) -> &str {
80 &self.caller
81 }
82 #[must_use]
84 pub fn release(&self) -> &str {
85 &self.release
86 }
87}