|
@@ -138,24 +138,38 @@ impl<'a, T: Modelable> Modelable for &'a T {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Modelable + serde::Serialize + serde::de::DeserializeOwned> Modelable for Vec<T> {
|
|
|
+impl<T: Modelable + serde::Serialize + serde::de::DeserializeOwned + 'static> Modelable for Vec<T> {
|
|
|
fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
|
|
|
+ // We serialize Vec<u8> types directly as a blob
|
|
|
+ if std::mem::size_of::<T>() == 1 && std::any::TypeId::of::<T>() == std::any::TypeId::of::<u8>() {
|
|
|
+ // this bit is unsafe, but is perfectly reasonable...
|
|
|
+ let byte_slice = unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
|
|
|
+ return byte_slice.bind_to(stmt, col)
|
|
|
+ }
|
|
|
serde_json::to_string(self).unwrap().bind_to(stmt, col)
|
|
|
}
|
|
|
fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
|
|
|
where
|
|
|
Self: Sized,
|
|
|
{
|
|
|
- // TODO: add special exception for one-byte datatypes
|
|
|
+ // Deserialize one-byte types directly from the blob
|
|
|
+ if std::mem::size_of::<T>() == 1 && std::any::TypeId::of::<T>() == std::any::TypeId::of::<u8>() {
|
|
|
+ let blob: Vec<u8> = stmt.read(col_offset)?;
|
|
|
|
|
|
- let s = String::build_from(stmt, col_offset)?;
|
|
|
- Ok((
|
|
|
- serde_json::from_str::<Vec<T>>(s.0.as_str()).map_err(|e| sqlite::Error {
|
|
|
- code: None,
|
|
|
- message: Some(e.to_string()),
|
|
|
- })?,
|
|
|
- 1,
|
|
|
- ))
|
|
|
+ // we know the return value is a u8 because the typeid matches, so while normally this
|
|
|
+ // is hilariously unsafe, right now it's perfectly okay.
|
|
|
+ Ok((unsafe { std::mem::transmute::<Vec<u8>, Vec<T>>(blob) }, 1))
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ let s = String::build_from(stmt, col_offset)?;
|
|
|
+ Ok((
|
|
|
+ serde_json::from_str::<Vec<T>>(s.0.as_str()).map_err(|e| sqlite::Error {
|
|
|
+ code: None,
|
|
|
+ message: Some(e.to_string()),
|
|
|
+ })?,
|
|
|
+ 1,
|
|
|
+ ))
|
|
|
+ }
|
|
|
}
|
|
|
fn column_type() -> &'static str where Self: Sized {
|
|
|
"blob"
|