Skip to main content

postgresql/
json.rs

1//! `json` / `jsonb` support via `serde`.
2//!
3//! [`Json`] stores any `serde`-serializable value in a PostgreSQL `json` or
4//! `jsonb` column. It is the escape hatch for the cases where the preferred
5//! `#[derive(Json)]` form cannot be used:
6//!
7//! * the type already derives [`FromRow`](crate::FromRow) and is row-shaped,
8//!   so deriving `Json` too would define `FromRow`/`RowShape` twice;
9//! * the value has no nameable type — for example a `HashMap` or a foreign
10//!   type — so there is nothing to put the derive on.
11//!
12//! Values are encoded as `jsonb`; on decode both `json` and `jsonb` columns are
13//! accepted.
14
15use std::ops::{Deref, DerefMut};
16
17/// A value stored as a PostgreSQL `json` / `jsonb` column.
18///
19/// Wrapping a value makes it a query parameter (encoded as `jsonb`) and lets
20/// it be decoded from a result column. See the crate documentation for the
21/// preferred `#[derive(Json)]` form and when to reach for this wrapper.
22///
23/// ```ignore
24/// #[derive(FromRow)]
25/// struct Something {
26///     id: i32,
27///     user: Json<HashMap<String, i32>>,
28/// }
29///
30/// query_as!(Something, "SELECT id, user FROM something")
31///     .fetch_all(&pool)
32///     .await?;
33/// query!("UPDATE something SET user = $1", something.user)
34///     .execute(&pool)
35///     .await?;
36/// ```
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
38pub struct Json<T>(pub T);
39
40impl<T> Json<T> {
41    /// Wraps `value` so it is stored as `jsonb`.
42    pub const fn new(value: T) -> Self {
43        Json(value)
44    }
45
46    /// Unwraps the value.
47    pub fn into_inner(self) -> T {
48        self.0
49    }
50}
51
52impl<T> Deref for Json<T> {
53    type Target = T;
54
55    fn deref(&self) -> &T {
56        &self.0
57    }
58}
59
60impl<T> DerefMut for Json<T> {
61    fn deref_mut(&mut self) -> &mut T {
62        &mut self.0
63    }
64}
65
66impl<T> AsRef<T> for Json<T> {
67    fn as_ref(&self) -> &T {
68        &self.0
69    }
70}
71
72impl<T> From<T> for Json<T> {
73    fn from(value: T) -> Self {
74        Json(value)
75    }
76}