|
@@ -0,0 +1,57 @@
|
|
|
+/// Wrapper struct to store a serializable object as JSON transparently in a text column
|
|
|
+pub struct JsonWrapper<T: serde::Serialize + serde::de::DeserializeOwned + 'static> {
|
|
|
+ wrap: T
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: serde::Serialize + serde::de::DeserializeOwned + 'static> JsonWrapper<T> {
|
|
|
+ pub fn wrap(wrap: T) -> Self {
|
|
|
+ Self { wrap }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn unwrap(self) -> T {
|
|
|
+ self.wrap
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: serde::Serialize + serde::de::DeserializeOwned + 'static> AsRef<T> for JsonWrapper<T> {
|
|
|
+ fn as_ref(&self) -> &T {
|
|
|
+ &self.wrap
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: serde::Serialize + serde::de::DeserializeOwned + 'static> AsMut<T> for JsonWrapper<T> {
|
|
|
+ fn as_mut(&mut self) -> &mut T {
|
|
|
+ &mut self.wrap
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: serde::Serialize + serde::de::DeserializeOwned + 'static> From<T> for JsonWrapper<T> {
|
|
|
+ fn from(wrap: T) -> Self {
|
|
|
+ Self { wrap }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: serde::Serialize + serde::de::DeserializeOwned + 'static> super::Modelable for JsonWrapper<T> {
|
|
|
+ fn bind_to(&self, stmt: &mut sqlite::Statement, col: usize) -> sqlite::Result<()> {
|
|
|
+ serde_json::to_string(&self.wrap).unwrap().bind_to(stmt, col)
|
|
|
+ }
|
|
|
+ fn build_from(stmt: &sqlite::Statement, col_offset: usize) -> sqlite::Result<(Self, usize)>
|
|
|
+ where
|
|
|
+ Self: Sized,
|
|
|
+ {
|
|
|
+ let s = String::build_from(stmt, col_offset)?;
|
|
|
+ Ok((
|
|
|
+ Self::wrap(serde_json::from_str::<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,
|
|
|
+ {
|
|
|
+ "text"
|
|
|
+ }
|
|
|
+}
|