Skip to main content

reef/
json.rs

1//! Typed JSON column wrappers.
2//!
3//! - [`Json<T>`] stores as TEXT (human-readable JSON)
4//! - [`Jsonb<T>`] stores as BLOB (SQLite 3.45+ binary JSONB encoding)
5//!
6//! Both newtypes are `#[serde(transparent)]`, so when used in RPC return
7//! types they serialize as the inner `T` directly — no extra wrapping in
8//! the wire format.
9//!
10//! `cargo reef db:push` recognizes these wrappers in schema field types and
11//! emits the corresponding SQL column type (`TEXT` or `BLOB`).
12//!
13//! SQL marshaling helpers (libsql `FromValue` / `IntoValue`) are not yet
14//! implemented — write your queries with `serde_json::to_string` / `from_str`
15//! against the inner `T` for now.
16
17use serde::{Deserialize, Serialize};
18use std::ops::{Deref, DerefMut};
19
20/// Wrap a serde-serializable value to mark a column as JSON-stored TEXT.
21#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[serde(transparent)]
23pub struct Json<T>(pub T);
24
25/// Wrap a serde-serializable value to mark a column as JSONB-stored BLOB.
26///
27/// Requires SQLite 3.45+ (libSQL inherits this). Faster to parse than
28/// [`Json<T>`] at the cost of opacity in the `sqlite3` shell.
29#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
30#[serde(transparent)]
31pub struct Jsonb<T>(pub T);
32
33macro_rules! impl_wrapper {
34    ($name:ident) => {
35        impl<T> $name<T> {
36            pub fn new(inner: T) -> Self {
37                Self(inner)
38            }
39            pub fn into_inner(self) -> T {
40                self.0
41            }
42        }
43        impl<T> Deref for $name<T> {
44            type Target = T;
45            fn deref(&self) -> &T {
46                &self.0
47            }
48        }
49        impl<T> DerefMut for $name<T> {
50            fn deref_mut(&mut self) -> &mut T {
51                &mut self.0
52            }
53        }
54        impl<T> From<T> for $name<T> {
55            fn from(inner: T) -> Self {
56                Self(inner)
57            }
58        }
59    };
60}
61
62impl_wrapper!(Json);
63impl_wrapper!(Jsonb);