aster_forge_cloud_files_core/
identity.rs1use std::fmt;
4
5use crate::{CloudFilesCoreError, Result};
6
7macro_rules! string_identity {
8 ($name:ident, $field:literal, $docs:literal) => {
9 #[doc = $docs]
10 #[derive(Clone, PartialEq, Eq, Hash)]
11 pub struct $name(String);
12
13 impl $name {
14 pub fn new(value: impl Into<String>) -> Result<Self> {
20 let value = value.into();
21 if value.is_empty() {
22 return Err(CloudFilesCoreError::empty($field));
23 }
24 Ok(Self(value))
25 }
26
27 pub fn as_str(&self) -> &str {
29 &self.0
30 }
31
32 pub fn into_string(self) -> String {
34 self.0
35 }
36 }
37
38 impl fmt::Debug for $name {
39 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
40 formatter
41 .debug_tuple(stringify!($name))
42 .field(&self.0)
43 .finish()
44 }
45 }
46
47 impl fmt::Display for $name {
48 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49 formatter.write_str(&self.0)
50 }
51 }
52 };
53}
54
55string_identity!(
56 CloudNamespaceId,
57 "cloud namespace id",
58 "Opaque identity namespace used to isolate unrelated backend identity spaces."
59);
60string_identity!(
61 CloudRootId,
62 "cloud root id",
63 "Stable root identity within one cloud namespace."
64);
65string_identity!(
66 CloudItemId,
67 "cloud item id",
68 "Stable path-independent item identity within one cloud root."
69);
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct CloudScope {
74 namespace_id: CloudNamespaceId,
75 root_id: CloudRootId,
76}
77
78impl CloudScope {
79 #[must_use]
81 pub const fn new(namespace_id: CloudNamespaceId, root_id: CloudRootId) -> Self {
82 Self {
83 namespace_id,
84 root_id,
85 }
86 }
87
88 #[must_use]
90 pub const fn namespace_id(&self) -> &CloudNamespaceId {
91 &self.namespace_id
92 }
93
94 #[must_use]
96 pub const fn root_id(&self) -> &CloudRootId {
97 &self.root_id
98 }
99
100 #[must_use]
102 pub fn into_parts(self) -> (CloudNamespaceId, CloudRootId) {
103 (self.namespace_id, self.root_id)
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Hash)]
112pub struct CloudItemKey {
113 scope: CloudScope,
114 item_id: CloudItemId,
115}
116
117impl CloudItemKey {
118 #[must_use]
120 pub const fn new(scope: CloudScope, item_id: CloudItemId) -> Self {
121 Self { scope, item_id }
122 }
123
124 #[must_use]
126 pub const fn scope(&self) -> &CloudScope {
127 &self.scope
128 }
129
130 #[must_use]
132 pub const fn item_id(&self) -> &CloudItemId {
133 &self.item_id
134 }
135
136 #[must_use]
138 pub fn into_parts(self) -> (CloudScope, CloudItemId) {
139 (self.scope, self.item_id)
140 }
141}