1use core::fmt;
5use core::sync::atomic::{AtomicU64, Ordering};
6extern crate alloc;
7use alloc::boxed::Box;
8use alloc::sync::{Arc, Weak};
9use alloc::vec::Vec;
10
11pub struct Blob<T> {
13 data: Arc<dyn AsRef<[T]> + Send + Sync>,
14 id: u64,
15}
16
17#[cfg(feature = "serde")]
18impl<T> serde::Serialize for Blob<T>
19where
20 [T]: serde_bytes::Serialize,
21{
22 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23 where
24 S: serde::ser::Serializer,
25 {
26 serde_bytes::serialize(self.data(), serializer)
27 }
28}
29
30#[cfg(feature = "serde")]
31impl<'de, T> serde::de::Deserialize<'de> for Blob<T>
32where
33 T: serde::de::Deserialize<'de> + Sync + Send + 'static,
34 Box<[u8]>: AsRef<[T]>,
35{
36 fn deserialize<D>(des: D) -> Result<Self, D::Error>
37 where
38 D: serde::de::Deserializer<'de>,
39 {
40 let byte_buf: serde_bytes::ByteBuf = serde_bytes::Deserialize::deserialize(des)?;
41 let boxed_slice: Box<[u8]> = byte_buf.into_boxed_slice();
42 Ok(Self::new(Arc::new(boxed_slice)))
43 }
44}
45
46impl<T> fmt::Debug for Blob<T> {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.debug_struct("Blob")
49 .field("id", &self.id)
50 .finish_non_exhaustive()
51 }
52}
53
54impl<T> PartialEq for Blob<T> {
55 fn eq(&self, other: &Self) -> bool {
56 self.id == other.id
57 }
58}
59
60impl<T> Clone for Blob<T> {
61 fn clone(&self) -> Self {
62 Self {
63 data: Arc::clone(&self.data),
64 id: self.id,
65 }
66 }
67}
68
69impl<T> AsRef<[T]> for Blob<T> {
70 fn as_ref(&self) -> &[T] {
71 self.data()
72 }
73}
74
75impl<T> From<Vec<T>> for Blob<T>
76where
77 T: 'static + Send + Sync,
78{
79 fn from(vec: Vec<T>) -> Self {
80 let boxed: Box<[T]> = vec.into();
81 Self::new(Arc::new(boxed))
82 }
83}
84
85static ID_COUNTER: AtomicU64 = AtomicU64::new(0);
86
87impl<T> Blob<T> {
88 pub fn new(data: Arc<dyn AsRef<[T]> + Send + Sync>) -> Self {
91 Self {
92 data,
93 id: ID_COUNTER.fetch_add(1, Ordering::Relaxed),
94 }
95 }
96
97 pub fn from_raw_parts(data: Arc<dyn AsRef<[T]> + Send + Sync>, id: u64) -> Self {
106 Self { data, id }
107 }
108
109 #[must_use]
111 pub fn into_raw_parts(self) -> (Arc<dyn AsRef<[T]> + Send + Sync>, u64) {
112 (self.data, self.id)
113 }
114
115 #[must_use]
117 pub fn len(&self) -> usize {
118 self.data().len()
119 }
120
121 #[must_use]
123 pub fn is_empty(&self) -> bool {
124 self.len() == 0
125 }
126
127 #[must_use]
129 pub fn data(&self) -> &[T] {
130 self.data.as_ref().as_ref()
131 }
132
133 #[must_use]
135 pub fn id(&self) -> u64 {
136 self.id
137 }
138
139 #[must_use]
141 pub fn strong_count(&self) -> usize {
142 Arc::strong_count(&self.data)
143 }
144
145 #[must_use]
147 pub fn downgrade(&self) -> WeakBlob<T> {
148 WeakBlob {
149 data: Arc::downgrade(&self.data),
150 id: self.id,
151 }
152 }
153}
154
155#[derive(Debug)]
157pub struct WeakBlob<T> {
158 data: Weak<dyn AsRef<[T]> + Send + Sync>,
159 id: u64,
160}
161
162impl<T> Clone for WeakBlob<T> {
163 fn clone(&self) -> Self {
164 Self {
165 data: Weak::clone(&self.data),
166 id: self.id,
167 }
168 }
169}
170
171impl<T> WeakBlob<T> {
172 #[must_use]
174 pub fn id(&self) -> u64 {
175 self.id
176 }
177
178 #[must_use]
181 pub fn upgrade(&self) -> Option<Blob<T>> {
182 Some(Blob {
183 data: self.data.upgrade()?,
184 id: self.id,
185 })
186 }
187}