sea_orm/value/
json.rs

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