diesel_json/
lib.rs

1//! Implements utility type for JSON, JSONB field handling in diesel
2
3#[macro_use]
4extern crate diesel;
5#[macro_use]
6extern crate serde;
7
8use diesel::pg::Pg;
9use diesel::sql_types;
10use diesel::{deserialize::FromSql, serialize::ToSql};
11use serde::de::DeserializeOwned;
12use serde::Serialize;
13use std::ops::{Deref, DerefMut};
14
15/// Wrapper type that implements Json data handling for postgres diesel connection
16///
17/// Use as wrapper for fields that are stored in Jsonb format
18/// ```ignore
19/// #[derive(serde::Serialize, serde::Deserialize, Debug)]
20/// pub struct ComplexStruct {
21///   // ...
22/// }
23///
24/// #[derive(serde::Serialize, serde::Deserialize,
25///          diesel::Queryable, diesel::Insertable)]
26/// pub struct ExampleTable {
27///     // Field that will be stored in Json, Jsonb format
28///     pub jsonb_field: diesel_json::Json<ComplexStruct>,
29/// }
30/// ```
31#[derive(FromSqlRow, AsExpression, Serialize, Deserialize, Debug, Clone)]
32#[serde(transparent)]
33#[sql_type = "sql_types::Jsonb"]
34pub struct Json<T: Sized>(pub T);
35
36impl<T> Json<T> {
37    pub fn new(value: T) -> Json<T> {
38        Json(value)
39    }
40}
41
42impl<T> Deref for Json<T> {
43    type Target = T;
44
45    fn deref(&self) -> &Self::Target {
46        &self.0
47    }
48}
49
50impl<T> DerefMut for Json<T> {
51    fn deref_mut(&mut self) -> &mut Self::Target {
52        &mut self.0
53    }
54}
55
56impl<T> AsRef<T> for Json<T> {
57    fn as_ref(&self) -> &T {
58        &self.0
59    }
60}
61
62impl<T> AsMut<T> for Json<T> {
63    fn as_mut(&mut self) -> &mut T {
64        &mut self.0
65    }
66}
67
68impl<T> FromSql<sql_types::Jsonb, Pg> for Json<T>
69where
70    T: std::fmt::Debug + DeserializeOwned,
71{
72    fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
73        let value = <serde_json::Value as FromSql<sql_types::Jsonb, Pg>>::from_sql(bytes)?;
74        Ok(Json(serde_json::from_value::<T>(value)?))
75    }
76}
77
78impl<T> ToSql<sql_types::Jsonb, Pg> for Json<T>
79where
80    T: std::fmt::Debug + Serialize,
81{
82    fn to_sql<W: std::io::Write>(
83        &self,
84        out: &mut diesel::serialize::Output<W, Pg>,
85    ) -> diesel::serialize::Result {
86        let value = serde_json::to_value(self)?;
87        <serde_json::Value as ToSql<sql_types::Jsonb, Pg>>::to_sql(&value, out)
88    }
89}
90
91impl<T> PartialEq for Json<T>
92where
93    T: PartialEq,
94{
95    fn eq(&self, other: &Self) -> bool {
96        self.0 == other.0
97    }
98}