Skip to main content

sea_query/value/
postgres_array.rs

1use super::*;
2use crate::RcOrArc;
3
4// We only implement conversion from Vec<T> to Array when T is not u8.
5// This is because for u8's case, there is already conversion to Byte defined above.
6// TODO When negative trait becomes a stable feature, following code can be much shorter.
7pub trait NotU8 {}
8
9impl NotU8 for bool {}
10impl NotU8 for i8 {}
11impl NotU8 for i16 {}
12impl NotU8 for i32 {}
13impl NotU8 for i64 {}
14impl NotU8 for u16 {}
15impl NotU8 for u32 {}
16impl NotU8 for u64 {}
17impl NotU8 for f32 {}
18impl NotU8 for f64 {}
19impl NotU8 for char {}
20impl NotU8 for String {}
21impl NotU8 for Vec<u8> {}
22
23#[cfg(feature = "with-json")]
24impl NotU8 for Json {}
25
26#[cfg(feature = "with-chrono")]
27impl NotU8 for NaiveDate {}
28
29#[cfg(feature = "with-chrono")]
30impl NotU8 for NaiveTime {}
31
32#[cfg(feature = "with-chrono")]
33impl NotU8 for NaiveDateTime {}
34
35#[cfg(feature = "with-chrono")]
36impl<Tz> NotU8 for DateTime<Tz> where Tz: chrono::TimeZone {}
37
38#[cfg(feature = "with-time")]
39impl NotU8 for time::Date {}
40
41#[cfg(feature = "with-time")]
42impl NotU8 for time::Time {}
43
44#[cfg(feature = "with-time")]
45impl NotU8 for PrimitiveDateTime {}
46
47#[cfg(feature = "with-time")]
48impl NotU8 for OffsetDateTime {}
49
50#[cfg(feature = "with-rust_decimal")]
51impl NotU8 for Decimal {}
52
53#[cfg(feature = "with-bigdecimal")]
54impl NotU8 for BigDecimal {}
55
56#[cfg(feature = "with-uuid")]
57impl NotU8 for Uuid {}
58
59#[cfg(feature = "with-uuid")]
60impl NotU8 for uuid::fmt::Braced {}
61
62#[cfg(feature = "with-uuid")]
63impl NotU8 for uuid::fmt::Hyphenated {}
64
65#[cfg(feature = "with-uuid")]
66impl NotU8 for uuid::fmt::Simple {}
67
68#[cfg(feature = "with-uuid")]
69impl NotU8 for uuid::fmt::Urn {}
70
71#[cfg(feature = "with-ipnetwork")]
72impl NotU8 for IpNetwork {}
73
74#[cfg(feature = "with-mac_address")]
75impl NotU8 for MacAddress {}
76
77/// If this blanket impl is causing trouble, please open an issue
78impl<T> NotU8 for &T where T: NotU8 {}
79
80impl<T> From<Vec<T>> for Value
81where
82    T: Into<Value> + NotU8 + ValueType,
83{
84    fn from(x: Vec<T>) -> Value {
85        Value::Array(
86            T::array_type(),
87            Some(Box::new(x.into_iter().map(|e| e.into()).collect())),
88        )
89    }
90}
91
92impl<T> Nullable for Vec<T>
93where
94    T: Into<Value> + NotU8 + ValueType,
95{
96    fn null() -> Value {
97        Value::Array(T::array_type(), None)
98    }
99}
100
101impl<T> ValueType for Vec<T>
102where
103    T: NotU8 + ValueType,
104{
105    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
106        match v {
107            Value::Array(ty, Some(v)) if T::array_type() == ty => {
108                Ok(v.into_iter().map(|e| e.unwrap()).collect())
109            }
110            _ => Err(ValueTypeErr),
111        }
112    }
113
114    fn type_name() -> String {
115        stringify!(Vec<T>).to_owned()
116    }
117
118    fn array_type() -> ArrayType {
119        T::array_type()
120    }
121
122    fn column_type() -> ColumnType {
123        use ColumnType::*;
124        Array(RcOrArc::new(T::column_type()))
125    }
126}
127
128impl Value {
129    pub fn is_array(&self) -> bool {
130        matches!(self, Self::Array(_, _))
131    }
132
133    pub fn as_ref_array(&self) -> Option<&Vec<Value>> {
134        match self {
135            Self::Array(_, v) => v.as_ref().map(|v| v.as_ref()),
136            _ => panic!("not Value::Array"),
137        }
138    }
139}