ic_backup/policy/ic_snapshot_transfer_read/
mod.rs1use super::response_identity::{ResponseIdentity, ResponseIdentityMismatch};
4use crate::model::{
5 attempt_journal::AttemptJournalRecord,
6 ic_snapshot_data::{IcSnapshotDataError, IcSnapshotDataReply},
7 ic_snapshot_metadata::{IcSnapshotMetadataError, IcSnapshotMetadataReply},
8 ic_snapshot_transfer_read::{
9 IcSnapshotTransferReadError, IcSnapshotTransferReadPayload, IcSnapshotTransferReadRequest,
10 IcSnapshotTransferReadResponse,
11 },
12};
13use thiserror::Error;
14
15#[derive(Debug)]
17pub enum IcSnapshotTransferReadReply<'request, 'metadata> {
18 Metadata(IcSnapshotMetadataReply<'request>),
20 Data(IcSnapshotDataReply<'request, 'metadata>),
22}
23
24#[derive(Debug)]
26pub struct IcSnapshotTransferReadView<'request, 'metadata> {
27 response: &'request IcSnapshotTransferReadResponse,
28 reply: IcSnapshotTransferReadReply<'request, 'metadata>,
29}
30
31impl<'request, 'metadata> IcSnapshotTransferReadView<'request, 'metadata> {
32 #[must_use]
34 pub const fn response(&self) -> &'request IcSnapshotTransferReadResponse {
35 self.response
36 }
37 #[must_use]
39 pub const fn reply(&self) -> &IcSnapshotTransferReadReply<'request, 'metadata> {
40 &self.reply
41 }
42}
43
44pub fn validate_response<'request, 'metadata>(
53 request: &IcSnapshotTransferReadRequest<'request, 'metadata>,
54 journal: &AttemptJournalRecord,
55 response: &'request IcSnapshotTransferReadResponse,
56) -> Result<IcSnapshotTransferReadView<'request, 'metadata>, IcSnapshotTransferReadAssociationError>
57{
58 request.validate_journal(journal)?;
59 let input = response.input();
60 ResponseIdentity {
61 authority: &input.authority,
62 mutation_attempt: input.mutation_attempt,
63 context: &input.context,
64 target: &input.target,
65 }
66 .compare(&ResponseIdentity {
67 authority: &request.authority().digest(),
68 mutation_attempt: request.mutation_attempt(),
69 context: request.plan().context(),
70 target: request.payload().target(),
71 })
72 .map_err(|mismatch| match mismatch {
73 ResponseIdentityMismatch::Authority => {
74 IcSnapshotTransferReadAssociationError::AuthorityMismatch
75 }
76 ResponseIdentityMismatch::Attempt => {
77 IcSnapshotTransferReadAssociationError::AttemptMismatch
78 }
79 ResponseIdentityMismatch::Context => {
80 IcSnapshotTransferReadAssociationError::ContextMismatch
81 }
82 ResponseIdentityMismatch::Target => IcSnapshotTransferReadAssociationError::TargetMismatch,
83 })?;
84 let reply = match request.payload() {
85 IcSnapshotTransferReadPayload::Metadata(payload) => IcSnapshotTransferReadReply::Metadata(
86 IcSnapshotMetadataReply::decode(payload, &input.reply)?,
87 ),
88 IcSnapshotTransferReadPayload::Data(payload) => {
89 IcSnapshotTransferReadReply::Data(IcSnapshotDataReply::decode(payload, &input.reply)?)
90 }
91 };
92 Ok(IcSnapshotTransferReadView { response, reply })
93}
94
95#[derive(Debug, Error)]
97pub enum IcSnapshotTransferReadAssociationError {
98 #[error(transparent)]
100 Reservation(#[from] IcSnapshotTransferReadError),
101 #[error("snapshot transfer read response authority differs")]
103 AuthorityMismatch,
104 #[error("snapshot transfer read response attempt differs")]
106 AttemptMismatch,
107 #[error("snapshot transfer read response context differs")]
109 ContextMismatch,
110 #[error("snapshot transfer read response target differs")]
112 TargetMismatch,
113 #[error(transparent)]
115 Metadata(#[from] IcSnapshotMetadataError),
116 #[error(transparent)]
118 Data(#[from] IcSnapshotDataError),
119}
120
121#[cfg(test)]
122mod tests;