1use std::fmt::{Debug, Formatter};
2use std::mem;
3use std::ops::Deref;
4
5use rkyv::de::deserializers::SharedDeserializeMap;
6use rkyv::validation::validators::DefaultValidator;
7use rkyv::{AlignedVec, Archive, CheckBytes, Deserialize};
8
9#[derive(Debug, thiserror::Error)]
10#[error("View cannot be made for type with provided data.")]
11pub struct InvalidView;
14
15pub struct DataView<T, D = AlignedVec>
20where
21 T: Archive,
22 T::Archived: 'static,
23 D: Deref<Target = [u8]> + Send + Sync,
24{
25 data: D,
29
30 view: &'static rkyv::Archived<T>,
32}
33
34impl<T, D> DataView<T, D>
35where
36 T: Archive,
37 T::Archived: CheckBytes<DefaultValidator<'static>> + 'static,
38 D: Deref<Target = [u8]> + Send + Sync,
39{
40 pub(crate) fn using(data: D) -> Result<Self, InvalidView> {
42 let extended_buf = unsafe { mem::transmute::<&[u8], &'static [u8]>(&data) };
46
47 let view =
48 rkyv::check_archived_root::<'_, T>(extended_buf).map_err(|_| InvalidView)?;
49
50 Ok(Self { data, view })
51 }
52
53 pub fn as_bytes(&self) -> &[u8] {
55 &self.data
56 }
57
58 pub fn into_data(self) -> D {
60 self.data
61 }
62}
63
64impl<T, D> DataView<T, D>
65where
66 T: Archive,
67 T::Archived: Deserialize<T, SharedDeserializeMap> + 'static,
68 D: Deref<Target = [u8]> + Send + Sync,
69{
70 pub fn to_owned(&self) -> Result<T, InvalidView> {
72 self.view
73 .deserialize(&mut SharedDeserializeMap::default())
74 .map_err(|_| InvalidView)
75 }
76}
77
78impl<T, D> Clone for DataView<T, D>
79where
80 T: Archive,
81 T::Archived: CheckBytes<DefaultValidator<'static>> + Debug,
82 D: Deref<Target = [u8]> + Send + Sync + Clone,
83{
84 fn clone(&self) -> Self {
85 Self::using(self.data.clone()).expect("BUG: Valid data has become invalid?")
86 }
87}
88
89impl<T, D> Debug for DataView<T, D>
90where
91 T: Archive,
92 T::Archived: CheckBytes<DefaultValidator<'static>> + Debug,
93 D: Deref<Target = [u8]> + Send + Sync,
94{
95 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96 self.view.fmt(f)
97 }
98}
99
100impl<T, D> Deref for DataView<T, D>
101where
102 T: Archive,
103 T::Archived: CheckBytes<DefaultValidator<'static>>,
104 D: Deref<Target = [u8]> + Send + Sync,
105{
106 type Target = T::Archived;
107
108 fn deref(&self) -> &Self::Target {
109 self.view
110 }
111}
112
113impl<T, D> PartialEq for DataView<T, D>
114where
115 T: Archive,
116 T::Archived: CheckBytes<DefaultValidator<'static>> + PartialEq,
117 D: Deref<Target = [u8]> + Send + Sync,
118{
119 fn eq(&self, other: &Self) -> bool {
120 self.view == other.view
121 }
122}
123
124impl<T, D> PartialEq<T> for DataView<T, D>
125where
126 T: Archive,
127 T::Archived: CheckBytes<DefaultValidator<'static>> + PartialEq<T>,
128 D: Deref<Target = [u8]> + Send + Sync,
129{
130 fn eq(&self, other: &T) -> bool {
131 self.view == other
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use rkyv::{Archive, Deserialize, Serialize};
138
139 use super::*;
140
141 #[repr(C)]
142 #[derive(Serialize, Deserialize, Archive, PartialEq, Eq, Debug)]
143 #[archive(compare(PartialEq), check_bytes)]
144 #[archive_attr(derive(Debug, PartialEq, Eq))]
145 struct Demo {
146 a: String,
147 b: u64,
148 }
149
150 #[test]
151 fn test_view() {
152 let demo = Demo {
153 a: "Jello".to_string(),
154 b: 133,
155 };
156
157 let bytes = rkyv::to_bytes::<_, 1024>(&demo).unwrap();
158 let view: DataView<Demo, _> = DataView::using(bytes).unwrap();
159 assert!(view == demo, "Original and view must match.");
160 }
161
162 #[test]
163 fn test_invalid_view() {
164 let res = DataView::<Demo, _>::using(b"Hello, world!".to_vec());
165 assert!(res.is_err(), "View should be rejected");
166 }
167
168 #[test]
169 fn test_deserialize() {
170 let demo = Demo {
171 a: "Jello".to_string(),
172 b: 133,
173 };
174
175 let bytes = rkyv::to_bytes::<_, 1024>(&demo).unwrap();
176 let view: DataView<Demo, _> = DataView::using(bytes).unwrap();
177 assert!(view == demo, "Original and view must match.");
178
179 let value = view.to_owned().unwrap();
180 assert_eq!(value, demo, "Deserialized and original value should match.")
181 }
182}