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