aster_forge_cloud_files_core/
revision.rs1use std::fmt;
4
5use crate::{CloudFilesCoreError, Result};
6
7macro_rules! opaque_revision {
8 ($name:ident, $field:literal, $docs:literal) => {
9 #[doc = $docs]
10 #[derive(Clone, PartialEq, Eq, Hash)]
11 pub struct $name(Vec<u8>);
12
13 impl $name {
14 pub fn new(value: impl Into<Vec<u8>>) -> 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 from_slice(value: &[u8]) -> Result<Self> {
33 Self::new(value.to_vec())
34 }
35
36 pub fn as_bytes(&self) -> &[u8] {
38 &self.0
39 }
40
41 pub fn into_bytes(self) -> Vec<u8> {
43 self.0
44 }
45 }
46
47 impl fmt::Debug for $name {
48 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49 formatter
50 .debug_struct(stringify!($name))
51 .field("byte_len", &self.0.len())
52 .finish()
53 }
54 }
55 };
56}
57
58opaque_revision!(
59 MetadataRevision,
60 "metadata revision",
61 "Opaque equality/precondition token for metadata state."
62);
63opaque_revision!(
64 ContentRevision,
65 "content revision",
66 "Opaque equality/precondition token for content state."
67);
68
69#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub struct ContentDigestAlgorithm(String);
72
73impl ContentDigestAlgorithm {
74 pub fn new(value: impl Into<String>) -> Result<Self> {
80 let value = value.into();
81 if value.is_empty() {
82 return Err(CloudFilesCoreError::empty("content digest algorithm"));
83 }
84 Ok(Self(value))
85 }
86
87 #[must_use]
89 pub fn as_str(&self) -> &str {
90 &self.0
91 }
92
93 #[must_use]
95 pub fn into_string(self) -> String {
96 self.0
97 }
98}
99
100#[derive(Clone, PartialEq, Eq, Hash)]
105pub struct ContentDigest {
106 algorithm: ContentDigestAlgorithm,
107 value: Vec<u8>,
108}
109
110impl ContentDigest {
111 pub fn new(algorithm: ContentDigestAlgorithm, value: impl Into<Vec<u8>>) -> Result<Self> {
117 let value = value.into();
118 if value.is_empty() {
119 return Err(CloudFilesCoreError::empty("content digest value"));
120 }
121 Ok(Self { algorithm, value })
122 }
123
124 #[must_use]
126 pub const fn algorithm(&self) -> &ContentDigestAlgorithm {
127 &self.algorithm
128 }
129
130 #[must_use]
132 pub fn value(&self) -> &[u8] {
133 &self.value
134 }
135
136 #[must_use]
138 pub fn into_parts(self) -> (ContentDigestAlgorithm, Vec<u8>) {
139 (self.algorithm, self.value)
140 }
141}
142
143impl fmt::Debug for ContentDigest {
144 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
145 formatter
146 .debug_struct("ContentDigest")
147 .field("algorithm", &self.algorithm)
148 .field("byte_len", &self.value.len())
149 .finish()
150 }
151}