1use std::ops::{Deref, DerefMut};
7
8use sqlx::database::Database;
9use sqlx::decode::Decode;
10use sqlx::encode::{Encode, IsNull};
11use sqlx::error::BoxDynError;
12use sqlx::sqlite::{SqliteArgumentValue, SqliteTypeInfo};
13use sqlx::types::Type;
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
59pub struct Rkyv<T: ?Sized>(pub T);
60
61impl<T> From<T> for Rkyv<T> {
62 fn from(value: T) -> Self {
63 Self(value)
64 }
65}
66
67impl<T> Deref for Rkyv<T> {
68 type Target = T;
69
70 fn deref(&self) -> &Self::Target {
71 &self.0
72 }
73}
74
75impl<T> DerefMut for Rkyv<T> {
76 fn deref_mut(&mut self) -> &mut Self::Target {
77 &mut self.0
78 }
79}
80
81impl<T> AsRef<T> for Rkyv<T> {
82 fn as_ref(&self) -> &T {
83 &self.0
84 }
85}
86
87impl<T> AsMut<T> for Rkyv<T> {
88 fn as_mut(&mut self) -> &mut T {
89 &mut self.0
90 }
91}
92
93impl<T> Rkyv<T>
94where
95 T: for<'a> rkyv::Serialize<
96 rkyv::rancor::Strategy<
97 rkyv::ser::Serializer<
98 rkyv::util::AlignedVec,
99 rkyv::ser::allocator::ArenaHandle<'a>,
100 rkyv::ser::sharing::Share,
101 >,
102 rkyv::rancor::Error,
103 >,
104 >,
105{
106 pub fn encode_to(&self) -> Result<Vec<u8>, rkyv::rancor::Error> {
112 let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&self.0)?;
113 Ok(bytes.to_vec())
114 }
115}
116
117impl<T> Rkyv<T>
118where
119 T: rkyv::Archive,
120 <T as rkyv::Archive>::Archived: for<'a> rkyv::bytecheck::CheckBytes<
121 rkyv::rancor::Strategy<
122 rkyv::validation::Validator<
123 rkyv::validation::archive::ArchiveValidator<'a>,
124 rkyv::validation::shared::SharedValidator,
125 >,
126 rkyv::rancor::Error,
127 >,
128 > + rkyv::Deserialize<T, rkyv::rancor::Strategy<rkyv::de::Pool, rkyv::rancor::Error>>,
129{
130 pub fn decode_from_bytes(bytes: &[u8]) -> Result<Self, rkyv::rancor::Error> {
136 let data = rkyv::from_bytes::<T, rkyv::rancor::Error>(bytes)?;
137 Ok(Self(data))
138 }
139}
140
141impl<T> Type<sqlx::Sqlite> for Rkyv<T> {
142 fn type_info() -> SqliteTypeInfo {
143 <&[u8] as Type<sqlx::Sqlite>>::type_info()
144 }
145
146 fn compatible(ty: &SqliteTypeInfo) -> bool {
147 <&[u8] as Type<sqlx::Sqlite>>::compatible(ty)
148 }
149}
150
151impl<T> Encode<'_, sqlx::Sqlite> for Rkyv<T>
152where
153 T: for<'a> rkyv::Serialize<
154 rkyv::rancor::Strategy<
155 rkyv::ser::Serializer<
156 rkyv::util::AlignedVec,
157 rkyv::ser::allocator::ArenaHandle<'a>,
158 rkyv::ser::sharing::Share,
159 >,
160 rkyv::rancor::Error,
161 >,
162 >,
163{
164 fn encode_by_ref(
165 &self,
166 buf: &mut <sqlx::Sqlite as Database>::ArgumentBuffer<'_>,
167 ) -> Result<IsNull, BoxDynError> {
168 let data = self.encode_to()?;
169 buf.push(SqliteArgumentValue::Blob(std::borrow::Cow::Owned(data)));
170
171 Ok(IsNull::No)
172 }
173}
174
175impl<'r, T> Decode<'r, sqlx::Sqlite> for Rkyv<T>
176where
177 T: rkyv::Archive,
178 <T as rkyv::Archive>::Archived: for<'a> rkyv::bytecheck::CheckBytes<
179 rkyv::rancor::Strategy<
180 rkyv::validation::Validator<
181 rkyv::validation::archive::ArchiveValidator<'a>,
182 rkyv::validation::shared::SharedValidator,
183 >,
184 rkyv::rancor::Error,
185 >,
186 > + rkyv::Deserialize<T, rkyv::rancor::Strategy<rkyv::de::Pool, rkyv::rancor::Error>>,
187 Vec<u8>: sqlx::Decode<'r, sqlx::Sqlite>,
188{
189 fn decode(value: <sqlx::Sqlite as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
190 let decoded = Vec::<u8>::decode(value)?;
191 let data = Rkyv::<T>::decode_from_bytes(&decoded[..])?;
192
193 Ok(data)
194 }
195}