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#[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 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}