sea_orm/value/
json.rs

1use crate::sea_query::{ArrayType, ColumnType, Nullable, ValueType, ValueTypeErr};
2use crate::{
3    ActiveValue, ColIdx, IntoActiveValue, QueryResult, TryGetError, TryGetable, Value,
4    error::json_err,
5};
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9/// Wrap a Rust value that should be encoded/decoded via a JSON/JSONB column.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct JsonField<T>(pub T);
12
13impl<T> From<T> for JsonField<T> {
14    fn from(value: T) -> Self {
15        Self(value)
16    }
17}
18
19impl<T> Serialize for JsonField<T>
20where
21    T: Serialize,
22{
23    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24    where
25        S: Serializer,
26    {
27        self.0.serialize(serializer)
28    }
29}
30
31impl<'de, T> Deserialize<'de> for JsonField<T>
32where
33    T: Deserialize<'de>,
34{
35    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36    where
37        D: Deserializer<'de>,
38    {
39        T::deserialize(deserializer).map(JsonField)
40    }
41}
42
43impl<T> From<JsonField<T>> for Value
44where
45    T: Serialize,
46{
47    fn from(source: JsonField<T>) -> Self {
48        Value::Json(Some(serde_json::to_value(source.0).expect(concat!(
49            "Failed to serialize JSON value for '",
50            stringify!(JsonField),
51            "'"
52        ))))
53    }
54}
55
56impl<T> ValueType for JsonField<T>
57where
58    for<'de> T: Deserialize<'de>,
59{
60    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
61        match v {
62            // TODO: Should we convert None to Null?
63            Value::Json(Some(json)) => serde_json::from_value(json)
64                .map(JsonField)
65                .map_err(|_| ValueTypeErr),
66            _ => Err(ValueTypeErr),
67        }
68    }
69
70    fn type_name() -> String {
71        format!("JsonField<{}>", std::any::type_name::<T>())
72    }
73
74    fn array_type() -> ArrayType {
75        ArrayType::Json
76    }
77
78    fn column_type() -> ColumnType {
79        ColumnType::Json
80    }
81}
82
83impl<T> Nullable for JsonField<T> {
84    fn null() -> Value {
85        Value::Json(None)
86    }
87}
88
89impl<T> IntoActiveValue<JsonField<T>> for JsonField<T>
90where
91    T: Serialize,
92{
93    fn into_active_value(self) -> ActiveValue<JsonField<T>> {
94        ActiveValue::Set(self)
95    }
96}
97
98impl<T> TryGetable for JsonField<T>
99where
100    for<'de> T: Deserialize<'de>,
101{
102    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {
103        let json = serde_json::Value::try_get_by(res, index)?;
104        serde_json::from_value(json)
105            .map(JsonField)
106            .map_err(|e| TryGetError::DbErr(json_err(e)))
107    }
108}