ic_backup/model/inventory/target/
mod.rs1use super::InventoryRecordError;
4use crate::model::artifacts::canonical_hash;
5use serde::{Deserialize, Serialize};
6
7pub const MAX_INVENTORY_ROLE_BYTES: usize = 256;
9
10#[derive(Clone, Debug)]
12pub struct InventoryTargetRequest {
13 pub canister_id: String,
15 pub parent_canister_id: Option<String>,
17 pub role: Option<String>,
19 pub module_hash: Option<String>,
21}
22
23#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
25#[serde(try_from = "TargetFields")]
26pub struct InventoryTargetRecord {
27 canister_id: String,
28 parent_canister_id: Option<String>,
29 role: Option<String>,
30 module_hash: Option<String>,
31}
32
33#[derive(Deserialize)]
34#[serde(deny_unknown_fields)]
35struct TargetFields {
36 canister_id: String,
37 #[serde(deserialize_with = "crate::model::required_option::deserialize")]
38 parent_canister_id: Option<String>,
39 #[serde(deserialize_with = "crate::model::required_option::deserialize")]
40 role: Option<String>,
41 #[serde(deserialize_with = "crate::model::required_option::deserialize")]
42 module_hash: Option<String>,
43}
44
45impl TryFrom<TargetFields> for InventoryTargetRecord {
46 type Error = InventoryRecordError;
47 fn try_from(fields: TargetFields) -> Result<Self, Self::Error> {
48 Self::new(&InventoryTargetRequest {
49 canister_id: fields.canister_id,
50 parent_canister_id: fields.parent_canister_id,
51 role: fields.role,
52 module_hash: fields.module_hash,
53 })
54 }
55}
56impl InventoryTargetRecord {
57 pub fn new(request: &InventoryTargetRequest) -> Result<Self, InventoryRecordError> {
62 if request
63 .role
64 .as_ref()
65 .is_some_and(|role| role.len() > MAX_INVENTORY_ROLE_BYTES)
66 {
67 return Err(InventoryRecordError::RoleTooLarge);
68 }
69 Ok(Self {
70 canister_id: crate::model::principal::canonical_text(&request.canister_id)
71 .ok_or(InventoryRecordError::InvalidPrincipal("canister_id"))?,
72 parent_canister_id: request
73 .parent_canister_id
74 .as_deref()
75 .map(|value| {
76 crate::model::principal::canonical_text(value)
77 .ok_or(InventoryRecordError::InvalidPrincipal("parent_canister_id"))
78 })
79 .transpose()?,
80 role: request.role.clone(),
81 module_hash: request
82 .module_hash
83 .as_deref()
84 .map(canonical_hash)
85 .transpose()?,
86 })
87 }
88 #[must_use]
90 pub fn canister_id(&self) -> &str {
91 &self.canister_id
92 }
93 #[must_use]
95 pub fn parent_canister_id(&self) -> Option<&str> {
96 self.parent_canister_id.as_deref()
97 }
98 #[must_use]
100 pub fn role(&self) -> Option<&str> {
101 self.role.as_deref()
102 }
103 #[must_use]
105 pub fn module_hash(&self) -> Option<&str> {
106 self.module_hash.as_deref()
107 }
108}