sea_query/value/
array.rs

1use super::*;
2use crate::RcOrArc;
3#[cfg(feature = "with-json")]
4use crate::backend::ValueEncoder;
5use std::sync::Arc;
6
7#[cfg(feature = "hashable-value")]
8mod hash;
9
10/// (type_name, values)
11type EnumArray = Box<(Arc<str>, Box<[Option<Arc<Enum>>]>)>;
12
13#[derive(Debug, Clone)]
14#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum Array {
17    Bool(Box<[Option<bool>]>),
18    TinyInt(Box<[Option<i8>]>),
19    SmallInt(Box<[Option<i16>]>),
20    Int(Box<[Option<i32>]>),
21    BigInt(Box<[Option<i64>]>),
22    TinyUnsigned(Box<[Option<u8>]>),
23    SmallUnsigned(Box<[Option<u16>]>),
24    Unsigned(Box<[Option<u32>]>),
25    BigUnsigned(Box<[Option<u64>]>),
26    Float(Box<[Option<f32>]>),
27    Double(Box<[Option<f64>]>),
28    String(Box<[Option<String>]>),
29    Char(Box<[Option<char>]>),
30    Bytes(Box<[Option<Vec<u8>>]>),
31    Enum(EnumArray),
32    #[cfg(feature = "with-json")]
33    Json(Box<[Option<Json>]>),
34    #[cfg(feature = "with-chrono")]
35    ChronoDate(Box<[Option<NaiveDate>]>),
36    #[cfg(feature = "with-chrono")]
37    ChronoTime(Box<[Option<NaiveTime>]>),
38    #[cfg(feature = "with-chrono")]
39    ChronoDateTime(Box<[Option<NaiveDateTime>]>),
40    #[cfg(feature = "with-chrono")]
41    ChronoDateTimeUtc(Box<[Option<DateTime<Utc>>]>),
42    #[cfg(feature = "with-chrono")]
43    ChronoDateTimeLocal(Box<[Option<DateTime<Local>>]>),
44    #[cfg(feature = "with-chrono")]
45    ChronoDateTimeWithTimeZone(Box<[Option<DateTime<FixedOffset>>]>),
46    #[cfg(feature = "with-time")]
47    TimeDate(Box<[Option<time::Date>]>),
48    #[cfg(feature = "with-time")]
49    TimeTime(Box<[Option<time::Time>]>),
50    #[cfg(feature = "with-time")]
51    TimeDateTime(Box<[Option<PrimitiveDateTime>]>),
52    #[cfg(feature = "with-time")]
53    TimeDateTimeWithTimeZone(Box<[Option<OffsetDateTime>]>),
54    #[cfg(feature = "with-jiff")]
55    JiffDate(Box<[Option<jiff::civil::Date>]>),
56    #[cfg(feature = "with-jiff")]
57    JiffTime(Box<[Option<jiff::civil::Time>]>),
58    #[cfg(feature = "with-jiff")]
59    JiffDateTime(Box<[Option<jiff::civil::DateTime>]>),
60    #[cfg(feature = "with-jiff")]
61    JiffTimestamp(Box<[Option<Timestamp>]>),
62    #[cfg(feature = "with-jiff")]
63    JiffZoned(Box<[Option<Zoned>]>),
64    #[cfg(feature = "with-uuid")]
65    Uuid(Box<[Option<Uuid>]>),
66    #[cfg(feature = "with-rust_decimal")]
67    Decimal(Box<[Option<Decimal>]>),
68    #[cfg(feature = "with-bigdecimal")]
69    BigDecimal(Box<[Option<BigDecimal>]>),
70    #[cfg(feature = "with-ipnetwork")]
71    IpNetwork(Box<[Option<IpNetwork>]>),
72    #[cfg(feature = "with-mac_address")]
73    MacAddress(Box<[Option<MacAddress>]>),
74    Null(ArrayType),
75}
76
77#[derive(Debug, Clone)]
78pub(crate) enum ArrayValueVec {
79    Bool(Vec<Option<bool>>),
80    TinyInt(Vec<Option<i8>>),
81    SmallInt(Vec<Option<i16>>),
82    Int(Vec<Option<i32>>),
83    BigInt(Vec<Option<i64>>),
84    TinyUnsigned(Vec<Option<u8>>),
85    SmallUnsigned(Vec<Option<u16>>),
86    Unsigned(Vec<Option<u32>>),
87    BigUnsigned(Vec<Option<u64>>),
88    Float(Vec<Option<f32>>),
89    Double(Vec<Option<f64>>),
90    String(Vec<Option<String>>),
91    Char(Vec<Option<char>>),
92    Bytes(Vec<Option<Vec<u8>>>),
93    Enum(Vec<Option<Arc<Enum>>>),
94    #[cfg(feature = "with-json")]
95    Json(Vec<Option<Json>>),
96    #[cfg(feature = "with-chrono")]
97    ChronoDate(Vec<Option<NaiveDate>>),
98    #[cfg(feature = "with-chrono")]
99    ChronoTime(Vec<Option<NaiveTime>>),
100    #[cfg(feature = "with-chrono")]
101    ChronoDateTime(Vec<Option<NaiveDateTime>>),
102    #[cfg(feature = "with-chrono")]
103    ChronoDateTimeUtc(Vec<Option<DateTime<Utc>>>),
104    #[cfg(feature = "with-chrono")]
105    ChronoDateTimeLocal(Vec<Option<DateTime<Local>>>),
106    #[cfg(feature = "with-chrono")]
107    ChronoDateTimeWithTimeZone(Vec<Option<DateTime<FixedOffset>>>),
108    #[cfg(feature = "with-time")]
109    TimeDate(Vec<Option<time::Date>>),
110    #[cfg(feature = "with-time")]
111    TimeTime(Vec<Option<time::Time>>),
112    #[cfg(feature = "with-time")]
113    TimeDateTime(Vec<Option<PrimitiveDateTime>>),
114    #[cfg(feature = "with-time")]
115    TimeDateTimeWithTimeZone(Vec<Option<OffsetDateTime>>),
116    #[cfg(feature = "with-jiff")]
117    JiffDate(Vec<Option<jiff::civil::Date>>),
118    #[cfg(feature = "with-jiff")]
119    JiffTime(Vec<Option<jiff::civil::Time>>),
120    #[cfg(feature = "with-jiff")]
121    JiffDateTime(Vec<Option<jiff::civil::DateTime>>),
122    #[cfg(feature = "with-jiff")]
123    JiffTimestamp(Vec<Option<Timestamp>>),
124    #[cfg(feature = "with-jiff")]
125    JiffZoned(Vec<Option<Zoned>>),
126    #[cfg(feature = "with-uuid")]
127    Uuid(Vec<Option<Uuid>>),
128    #[cfg(feature = "with-rust_decimal")]
129    Decimal(Vec<Option<Decimal>>),
130    #[cfg(feature = "with-bigdecimal")]
131    BigDecimal(Vec<Option<BigDecimal>>),
132    #[cfg(feature = "with-ipnetwork")]
133    IpNetwork(Vec<Option<IpNetwork>>),
134    #[cfg(feature = "with-mac_address")]
135    MacAddress(Vec<Option<MacAddress>>),
136}
137
138pub struct ArrayIterValue<'a>(Box<dyn Iterator<Item = Option<Value>> + 'a>);
139
140impl Array {
141    pub fn array_type(&self) -> ArrayType {
142        match self {
143            Array::Bool(_) => ArrayType::Bool,
144            Array::TinyInt(_) => ArrayType::TinyInt,
145            Array::SmallInt(_) => ArrayType::SmallInt,
146            Array::Int(_) => ArrayType::Int,
147            Array::BigInt(_) => ArrayType::BigInt,
148            Array::TinyUnsigned(_) => ArrayType::TinyUnsigned,
149            Array::SmallUnsigned(_) => ArrayType::SmallUnsigned,
150            Array::Unsigned(_) => ArrayType::Unsigned,
151            Array::BigUnsigned(_) => ArrayType::BigUnsigned,
152            Array::Float(_) => ArrayType::Float,
153            Array::Double(_) => ArrayType::Double,
154            Array::String(_) => ArrayType::String,
155            Array::Char(_) => ArrayType::Char,
156            Array::Bytes(_) => ArrayType::Bytes,
157            Array::Enum(boxed) => ArrayType::Enum(boxed.as_ref().0.clone()),
158            #[cfg(feature = "with-json")]
159            Array::Json(_) => ArrayType::Json,
160            #[cfg(feature = "with-chrono")]
161            Array::ChronoDate(_) => ArrayType::ChronoDate,
162            #[cfg(feature = "with-chrono")]
163            Array::ChronoTime(_) => ArrayType::ChronoTime,
164            #[cfg(feature = "with-chrono")]
165            Array::ChronoDateTime(_) => ArrayType::ChronoDateTime,
166            #[cfg(feature = "with-chrono")]
167            Array::ChronoDateTimeUtc(_) => ArrayType::ChronoDateTimeUtc,
168            #[cfg(feature = "with-chrono")]
169            Array::ChronoDateTimeLocal(_) => ArrayType::ChronoDateTimeLocal,
170            #[cfg(feature = "with-chrono")]
171            Array::ChronoDateTimeWithTimeZone(_) => ArrayType::ChronoDateTimeWithTimeZone,
172            #[cfg(feature = "with-time")]
173            Array::TimeDate(_) => ArrayType::TimeDate,
174            #[cfg(feature = "with-time")]
175            Array::TimeTime(_) => ArrayType::TimeTime,
176            #[cfg(feature = "with-time")]
177            Array::TimeDateTime(_) => ArrayType::TimeDateTime,
178            #[cfg(feature = "with-time")]
179            Array::TimeDateTimeWithTimeZone(_) => ArrayType::TimeDateTimeWithTimeZone,
180            #[cfg(feature = "with-jiff")]
181            Array::JiffDate(_) => ArrayType::JiffDate,
182            #[cfg(feature = "with-jiff")]
183            Array::JiffTime(_) => ArrayType::JiffTime,
184            #[cfg(feature = "with-jiff")]
185            Array::JiffDateTime(_) => ArrayType::JiffDateTime,
186            #[cfg(feature = "with-jiff")]
187            Array::JiffTimestamp(_) => ArrayType::JiffTimestamp,
188            #[cfg(feature = "with-jiff")]
189            Array::JiffZoned(_) => ArrayType::JiffZoned,
190            #[cfg(feature = "with-uuid")]
191            Array::Uuid(_) => ArrayType::Uuid,
192            #[cfg(feature = "with-rust_decimal")]
193            Array::Decimal(_) => ArrayType::Decimal,
194            #[cfg(feature = "with-bigdecimal")]
195            Array::BigDecimal(_) => ArrayType::BigDecimal,
196            #[cfg(feature = "with-ipnetwork")]
197            Array::IpNetwork(_) => ArrayType::IpNetwork,
198            #[cfg(feature = "with-mac_address")]
199            Array::MacAddress(_) => ArrayType::MacAddress,
200            Array::Null(ty) => ty.clone(),
201        }
202    }
203
204    pub fn is_null(&self) -> bool {
205        matches!(self, Array::Null(_))
206    }
207
208    pub fn is_empty(&self) -> bool {
209        match self {
210            Array::Bool(v) => v.is_empty(),
211            Array::TinyInt(v) => v.is_empty(),
212            Array::SmallInt(v) => v.is_empty(),
213            Array::Int(v) => v.is_empty(),
214            Array::BigInt(v) => v.is_empty(),
215            Array::TinyUnsigned(v) => v.is_empty(),
216            Array::SmallUnsigned(v) => v.is_empty(),
217            Array::Unsigned(v) => v.is_empty(),
218            Array::BigUnsigned(v) => v.is_empty(),
219            Array::Float(v) => v.is_empty(),
220            Array::Double(v) => v.is_empty(),
221            Array::String(v) => v.is_empty(),
222            Array::Char(v) => v.is_empty(),
223            Array::Bytes(v) => v.is_empty(),
224            Array::Enum(b) => b.as_ref().1.is_empty(),
225            #[cfg(feature = "with-json")]
226            Array::Json(v) => v.is_empty(),
227            #[cfg(feature = "with-chrono")]
228            Array::ChronoDate(v) => v.is_empty(),
229            #[cfg(feature = "with-chrono")]
230            Array::ChronoTime(v) => v.is_empty(),
231            #[cfg(feature = "with-chrono")]
232            Array::ChronoDateTime(v) => v.is_empty(),
233            #[cfg(feature = "with-chrono")]
234            Array::ChronoDateTimeUtc(v) => v.is_empty(),
235            #[cfg(feature = "with-chrono")]
236            Array::ChronoDateTimeLocal(v) => v.is_empty(),
237            #[cfg(feature = "with-chrono")]
238            Array::ChronoDateTimeWithTimeZone(v) => v.is_empty(),
239            #[cfg(feature = "with-time")]
240            Array::TimeDate(v) => v.is_empty(),
241            #[cfg(feature = "with-time")]
242            Array::TimeTime(v) => v.is_empty(),
243            #[cfg(feature = "with-time")]
244            Array::TimeDateTime(v) => v.is_empty(),
245            #[cfg(feature = "with-time")]
246            Array::TimeDateTimeWithTimeZone(v) => v.is_empty(),
247            #[cfg(feature = "with-jiff")]
248            Array::JiffDate(v) => v.is_empty(),
249            #[cfg(feature = "with-jiff")]
250            Array::JiffTime(v) => v.is_empty(),
251            #[cfg(feature = "with-jiff")]
252            Array::JiffDateTime(v) => v.is_empty(),
253            #[cfg(feature = "with-jiff")]
254            Array::JiffTimestamp(v) => v.is_empty(),
255            #[cfg(feature = "with-jiff")]
256            Array::JiffZoned(v) => v.is_empty(),
257            #[cfg(feature = "with-uuid")]
258            Array::Uuid(v) => v.is_empty(),
259            #[cfg(feature = "with-rust_decimal")]
260            Array::Decimal(v) => v.is_empty(),
261            #[cfg(feature = "with-bigdecimal")]
262            Array::BigDecimal(v) => v.is_empty(),
263            #[cfg(feature = "with-ipnetwork")]
264            Array::IpNetwork(v) => v.is_empty(),
265            #[cfg(feature = "with-mac_address")]
266            Array::MacAddress(v) => v.is_empty(),
267            Array::Null(_) => true,
268        }
269    }
270
271    pub fn iter_value(&self) -> ArrayIterValue<'_> {
272        fn map_value<T>(t: &Option<T>) -> Option<Value>
273        where
274            T: Clone,
275            Value: From<T>,
276        {
277            t.to_owned().map(Value::from)
278        }
279
280        ArrayIterValue(match self {
281            Array::Bool(v) => Box::new(v.iter().map(map_value)),
282            Array::TinyInt(v) => Box::new(v.iter().map(map_value)),
283            Array::SmallInt(v) => Box::new(v.iter().map(map_value)),
284            Array::Int(v) => Box::new(v.iter().map(map_value)),
285            Array::BigInt(v) => Box::new(v.iter().map(map_value)),
286            Array::TinyUnsigned(v) => Box::new(v.iter().map(map_value)),
287            Array::SmallUnsigned(v) => Box::new(v.iter().map(map_value)),
288            Array::Unsigned(v) => Box::new(v.iter().map(map_value)),
289            Array::BigUnsigned(v) => Box::new(v.iter().map(map_value)),
290            Array::Float(v) => Box::new(v.iter().map(map_value)),
291            Array::Double(v) => Box::new(v.iter().map(map_value)),
292            Array::String(v) => Box::new(v.iter().map(map_value)),
293            Array::Char(v) => Box::new(v.iter().map(map_value)),
294            Array::Bytes(v) => Box::new(v.iter().map(map_value)),
295            Array::Enum(v) => {
296                let (_, arr) = v.as_ref();
297                Box::new(arr.iter().map(|v| Some(Value::Enum(v.clone()))))
298            }
299            #[cfg(feature = "with-json")]
300            Array::Json(v) => Box::new(v.iter().map(map_value)),
301            #[cfg(feature = "with-chrono")]
302            Array::ChronoDate(v) => Box::new(v.iter().map(map_value)),
303            #[cfg(feature = "with-chrono")]
304            Array::ChronoTime(v) => Box::new(v.iter().map(map_value)),
305            #[cfg(feature = "with-chrono")]
306            Array::ChronoDateTime(v) => Box::new(v.iter().map(map_value)),
307            #[cfg(feature = "with-chrono")]
308            Array::ChronoDateTimeUtc(v) => Box::new(v.iter().map(map_value)),
309            #[cfg(feature = "with-chrono")]
310            Array::ChronoDateTimeLocal(v) => Box::new(v.iter().map(map_value)),
311            #[cfg(feature = "with-chrono")]
312            Array::ChronoDateTimeWithTimeZone(v) => Box::new(v.iter().map(map_value)),
313            #[cfg(feature = "with-time")]
314            Array::TimeDate(v) => Box::new(v.iter().map(map_value)),
315            #[cfg(feature = "with-time")]
316            Array::TimeTime(v) => Box::new(v.iter().map(map_value)),
317            #[cfg(feature = "with-time")]
318            Array::TimeDateTime(v) => Box::new(v.iter().map(map_value)),
319            #[cfg(feature = "with-time")]
320            Array::TimeDateTimeWithTimeZone(v) => Box::new(v.iter().map(map_value)),
321            #[cfg(feature = "with-jiff")]
322            Array::JiffDate(v) => Box::new(v.iter().map(map_value)),
323            #[cfg(feature = "with-jiff")]
324            Array::JiffTime(v) => Box::new(v.iter().map(map_value)),
325            #[cfg(feature = "with-jiff")]
326            Array::JiffDateTime(v) => Box::new(v.iter().map(map_value)),
327            #[cfg(feature = "with-jiff")]
328            Array::JiffTimestamp(v) => Box::new(v.iter().map(map_value)),
329            #[cfg(feature = "with-jiff")]
330            Array::JiffZoned(v) => Box::new(v.iter().map(map_value)),
331            #[cfg(feature = "with-uuid")]
332            Array::Uuid(v) => Box::new(v.iter().map(map_value)),
333            #[cfg(feature = "with-rust_decimal")]
334            Array::Decimal(v) => Box::new(v.iter().map(map_value)),
335            #[cfg(feature = "with-bigdecimal")]
336            Array::BigDecimal(v) => Box::new(v.iter().map(map_value)),
337            #[cfg(feature = "with-ipnetwork")]
338            Array::IpNetwork(v) => Box::new(v.iter().map(map_value)),
339            #[cfg(feature = "with-mac_address")]
340            Array::MacAddress(v) => Box::new(v.iter().map(map_value)),
341            Array::Null(_) => Box::new(std::iter::empty()),
342        })
343    }
344
345    fn into_array_value_vec(self) -> ArrayValueVec {
346        match self {
347            Array::Bool(v) => ArrayValueVec::Bool(Vec::from(v)),
348            Array::TinyInt(v) => ArrayValueVec::TinyInt(Vec::from(v)),
349            Array::SmallInt(v) => ArrayValueVec::SmallInt(Vec::from(v)),
350            Array::Int(v) => ArrayValueVec::Int(Vec::from(v)),
351            Array::BigInt(v) => ArrayValueVec::BigInt(Vec::from(v)),
352            Array::TinyUnsigned(v) => ArrayValueVec::TinyUnsigned(Vec::from(v)),
353            Array::SmallUnsigned(v) => ArrayValueVec::SmallUnsigned(Vec::from(v)),
354            Array::Unsigned(v) => ArrayValueVec::Unsigned(Vec::from(v)),
355            Array::BigUnsigned(v) => ArrayValueVec::BigUnsigned(Vec::from(v)),
356            Array::Float(v) => ArrayValueVec::Float(Vec::from(v)),
357            Array::Double(v) => ArrayValueVec::Double(Vec::from(v)),
358            Array::String(v) => ArrayValueVec::String(Vec::from(v)),
359            Array::Char(v) => ArrayValueVec::Char(Vec::from(v)),
360            Array::Bytes(v) => ArrayValueVec::Bytes(Vec::from(v)),
361            Array::Enum(boxed) => ArrayValueVec::Enum(Vec::from(boxed.1)),
362            #[cfg(feature = "with-json")]
363            Array::Json(v) => ArrayValueVec::Json(Vec::from(v)),
364            #[cfg(feature = "with-chrono")]
365            Array::ChronoDate(v) => ArrayValueVec::ChronoDate(Vec::from(v)),
366            #[cfg(feature = "with-chrono")]
367            Array::ChronoTime(v) => ArrayValueVec::ChronoTime(Vec::from(v)),
368            #[cfg(feature = "with-chrono")]
369            Array::ChronoDateTime(v) => ArrayValueVec::ChronoDateTime(Vec::from(v)),
370            #[cfg(feature = "with-chrono")]
371            Array::ChronoDateTimeUtc(v) => ArrayValueVec::ChronoDateTimeUtc(Vec::from(v)),
372            #[cfg(feature = "with-chrono")]
373            Array::ChronoDateTimeLocal(v) => ArrayValueVec::ChronoDateTimeLocal(Vec::from(v)),
374            #[cfg(feature = "with-chrono")]
375            Array::ChronoDateTimeWithTimeZone(v) => {
376                ArrayValueVec::ChronoDateTimeWithTimeZone(Vec::from(v))
377            }
378            #[cfg(feature = "with-time")]
379            Array::TimeDate(v) => ArrayValueVec::TimeDate(Vec::from(v)),
380            #[cfg(feature = "with-time")]
381            Array::TimeTime(v) => ArrayValueVec::TimeTime(Vec::from(v)),
382            #[cfg(feature = "with-time")]
383            Array::TimeDateTime(v) => ArrayValueVec::TimeDateTime(Vec::from(v)),
384            #[cfg(feature = "with-time")]
385            Array::TimeDateTimeWithTimeZone(v) => {
386                ArrayValueVec::TimeDateTimeWithTimeZone(Vec::from(v))
387            }
388            #[cfg(feature = "with-jiff")]
389            Array::JiffDate(v) => ArrayValueVec::JiffDate(Vec::from(v)),
390            #[cfg(feature = "with-jiff")]
391            Array::JiffTime(v) => ArrayValueVec::JiffTime(Vec::from(v)),
392            #[cfg(feature = "with-jiff")]
393            Array::JiffDateTime(v) => ArrayValueVec::JiffDateTime(Vec::from(v)),
394            #[cfg(feature = "with-jiff")]
395            Array::JiffTimestamp(v) => ArrayValueVec::JiffTimestamp(Vec::from(v)),
396            #[cfg(feature = "with-jiff")]
397            Array::JiffZoned(v) => ArrayValueVec::JiffZoned(Vec::from(v)),
398            #[cfg(feature = "with-uuid")]
399            Array::Uuid(v) => ArrayValueVec::Uuid(Vec::from(v)),
400            #[cfg(feature = "with-rust_decimal")]
401            Array::Decimal(v) => ArrayValueVec::Decimal(Vec::from(v)),
402            #[cfg(feature = "with-bigdecimal")]
403            Array::BigDecimal(v) => ArrayValueVec::BigDecimal(Vec::from(v)),
404            #[cfg(feature = "with-ipnetwork")]
405            Array::IpNetwork(v) => ArrayValueVec::IpNetwork(Vec::from(v)),
406            #[cfg(feature = "with-mac_address")]
407            Array::MacAddress(v) => ArrayValueVec::MacAddress(Vec::from(v)),
408            Array::Null(_) => panic!("Array cannot be Null"),
409        }
410    }
411
412    #[cfg(feature = "with-json")]
413    pub(crate) fn to_json_value(&self) -> Json {
414        fn map_slice_of_opts<T, F>(slice: &[Option<T>], mut f: F) -> Json
415        where
416            F: FnMut(&T) -> Json,
417        {
418            slice
419                .iter()
420                .map(|o| match o.as_ref() {
421                    Some(v) => f(v),
422                    None => Json::Null,
423                })
424                .collect()
425        }
426
427        fn encode_to_string<F>(f: F) -> String
428        where
429            F: FnOnce(&CommonSqlQueryBuilder, &mut String),
430        {
431            let mut s = String::new();
432            let enc = CommonSqlQueryBuilder;
433            f(&enc, &mut s);
434            s
435        }
436
437        match self {
438            Array::Bool(v) => map_slice_of_opts(v, |&b| Json::Bool(b)),
439            Array::TinyInt(v) => map_slice_of_opts(v, |&x| x.into()),
440            Array::SmallInt(v) => map_slice_of_opts(v, |&x| x.into()),
441            Array::Int(v) => map_slice_of_opts(v, |&x| x.into()),
442            Array::BigInt(v) => map_slice_of_opts(v, |&x| x.into()),
443            Array::TinyUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
444            Array::SmallUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
445            Array::Unsigned(v) => map_slice_of_opts(v, |&x| x.into()),
446            Array::BigUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
447            Array::Float(v) => map_slice_of_opts(v, |&x| x.into()),
448            Array::Double(v) => map_slice_of_opts(v, |&x| x.into()),
449            Array::String(v) => map_slice_of_opts(v, |s| Json::String(s.clone())),
450            Array::Char(v) => map_slice_of_opts(v, |&c| Json::String(c.to_string())),
451            Array::Bytes(v) => map_slice_of_opts(v, |bytes| {
452                Json::String(std::str::from_utf8(bytes).unwrap().to_string())
453            }),
454            Array::Enum(v) => {
455                let (_, arr) = v.as_ref();
456                map_slice_of_opts(arr, |e| Json::String(e.value.to_string()))
457            }
458            #[cfg(feature = "with-json")]
459            Array::Json(v) => map_slice_of_opts(v, |j| j.clone()),
460            #[cfg(feature = "with-chrono")]
461            Array::ChronoDate(v) => map_slice_of_opts(v, |&d| {
462                Json::String(encode_to_string(|enc, buf| enc.write_naive_date_to(buf, d)))
463            }),
464            #[cfg(feature = "with-chrono")]
465            Array::ChronoTime(v) => map_slice_of_opts(v, |&t| {
466                Json::String(encode_to_string(|enc, buf| enc.write_naive_time_to(buf, t)))
467            }),
468            #[cfg(feature = "with-chrono")]
469            Array::ChronoDateTime(v) => map_slice_of_opts(v, |&dt| {
470                Json::String(encode_to_string(|enc, buf| {
471                    enc.write_naive_datetime_to(buf, dt)
472                }))
473            }),
474            #[cfg(feature = "with-chrono")]
475            Array::ChronoDateTimeUtc(v) => map_slice_of_opts(v, |dt| {
476                Json::String(encode_to_string(|enc, buf| {
477                    enc.write_datetime_utc_to(buf, dt)
478                }))
479            }),
480            #[cfg(feature = "with-chrono")]
481            Array::ChronoDateTimeLocal(v) => map_slice_of_opts(v, |dt| {
482                Json::String(encode_to_string(|enc, buf| {
483                    enc.write_datetime_local_to(buf, dt)
484                }))
485            }),
486            #[cfg(feature = "with-chrono")]
487            Array::ChronoDateTimeWithTimeZone(v) => map_slice_of_opts(v, |dt| {
488                Json::String(encode_to_string(|enc, buf| {
489                    enc.write_datetime_fixed_to(buf, dt)
490                }))
491            }),
492            #[cfg(feature = "with-time")]
493            Array::TimeDate(v) => map_slice_of_opts(v, |&d| {
494                Json::String(encode_to_string(|enc, buf| enc.write_time_date_to(buf, d)))
495            }),
496            #[cfg(feature = "with-time")]
497            Array::TimeTime(v) => map_slice_of_opts(v, |&t| {
498                Json::String(encode_to_string(|enc, buf| enc.write_time_time_to(buf, t)))
499            }),
500            #[cfg(feature = "with-time")]
501            Array::TimeDateTime(v) => map_slice_of_opts(v, |&dt| {
502                Json::String(encode_to_string(|enc, buf| {
503                    enc.write_time_datetime_to(buf, dt)
504                }))
505            }),
506            #[cfg(feature = "with-time")]
507            Array::TimeDateTimeWithTimeZone(v) => map_slice_of_opts(v, |&dt| {
508                Json::String(encode_to_string(|enc, buf| {
509                    enc.write_time_datetime_tz_to(buf, dt)
510                }))
511            }),
512            #[cfg(feature = "with-jiff")]
513            Array::JiffDate(v) => map_slice_of_opts(v, |&d| {
514                Json::String(encode_to_string(|enc, buf| enc.write_jiff_date_to(buf, d)))
515            }),
516            #[cfg(feature = "with-jiff")]
517            Array::JiffTime(v) => map_slice_of_opts(v, |&t| {
518                Json::String(encode_to_string(|enc, buf| enc.write_jiff_time_to(buf, t)))
519            }),
520            #[cfg(feature = "with-jiff")]
521            Array::JiffDateTime(v) => map_slice_of_opts(v, |&dt| {
522                Json::String(encode_to_string(|enc, buf| {
523                    enc.write_jiff_datetime_to(buf, dt)
524                }))
525            }),
526            #[cfg(feature = "with-jiff")]
527            Array::JiffTimestamp(v) => map_slice_of_opts(v, |&ts| {
528                Json::String(encode_to_string(|enc, buf| {
529                    enc.write_jiff_timestamp_to(buf, ts)
530                }))
531            }),
532            #[cfg(feature = "with-jiff")]
533            Array::JiffZoned(v) => map_slice_of_opts(v, |z| {
534                Json::String(encode_to_string(|enc, buf| enc.write_jiff_zoned_to(buf, z)))
535            }),
536            #[cfg(feature = "with-uuid")]
537            Array::Uuid(v) => map_slice_of_opts(v, |&u| Json::String(u.to_string())),
538            #[cfg(feature = "with-rust_decimal")]
539            Array::Decimal(v) => map_slice_of_opts(v, |&d| {
540                use rust_decimal::prelude::ToPrimitive;
541                Json::Number(serde_json::Number::from_f64(d.to_f64().unwrap()).unwrap())
542            }),
543            #[cfg(feature = "with-bigdecimal")]
544            Array::BigDecimal(v) => map_slice_of_opts(v, |bd| {
545                use bigdecimal::ToPrimitive;
546                Json::Number(serde_json::Number::from_f64(bd.to_f64().unwrap()).unwrap())
547            }),
548            #[cfg(feature = "with-ipnetwork")]
549            Array::IpNetwork(v) => map_slice_of_opts(v, |&ip| {
550                Json::String(encode_to_string(|enc, buf| enc.write_ipnetwork_to(buf, ip)))
551            }),
552            #[cfg(feature = "with-mac_address")]
553            Array::MacAddress(v) => map_slice_of_opts(v, |&mac| {
554                Json::String(encode_to_string(|enc, buf| {
555                    enc.write_mac_address_to(buf, mac)
556                }))
557            }),
558            Array::Null(_) => Json::Null,
559        }
560    }
561
562    pub fn dummy_value(&self) -> Self {
563        match self {
564            Array::Bool(_) => Array::Bool(Box::new([])),
565            Array::TinyInt(_) => Array::TinyInt(Box::new([])),
566            Array::SmallInt(_) => Array::SmallInt(Box::new([])),
567            Array::Int(_) => Array::Int(Box::new([])),
568            Array::BigInt(_) => Array::BigInt(Box::new([])),
569            Array::TinyUnsigned(_) => Array::TinyUnsigned(Box::new([])),
570            Array::SmallUnsigned(_) => Array::SmallUnsigned(Box::new([])),
571            Array::Unsigned(_) => Array::Unsigned(Box::new([])),
572            Array::BigUnsigned(_) => Array::BigUnsigned(Box::new([])),
573            Array::Float(_) => Array::Float(Box::new([])),
574            Array::Double(_) => Array::Double(Box::new([])),
575            Array::String(_) => Array::String(Box::new([])),
576            Array::Char(_) => Array::Char(Box::new([])),
577            Array::Bytes(_) => Array::Bytes(Box::new([])),
578            Array::Enum(val) => {
579                let val = val.as_ref();
580                Array::Enum(Box::new((val.0.clone(), Box::new([]))))
581            }
582            #[cfg(feature = "with-json")]
583            Array::Json(_) => Array::Json(Box::new([])),
584            #[cfg(feature = "with-chrono")]
585            Array::ChronoDate(_) => Array::ChronoDate(Box::new([])),
586            #[cfg(feature = "with-chrono")]
587            Array::ChronoTime(_) => Array::ChronoTime(Box::new([])),
588            #[cfg(feature = "with-chrono")]
589            Array::ChronoDateTime(_) => Array::ChronoDateTime(Box::new([])),
590            #[cfg(feature = "with-chrono")]
591            Array::ChronoDateTimeUtc(_) => Array::ChronoDateTimeUtc(Box::new([])),
592            #[cfg(feature = "with-chrono")]
593            Array::ChronoDateTimeLocal(_) => Array::ChronoDateTimeLocal(Box::new([])),
594            #[cfg(feature = "with-chrono")]
595            Array::ChronoDateTimeWithTimeZone(_) => Array::ChronoDateTimeWithTimeZone(Box::new([])),
596            #[cfg(feature = "with-time")]
597            Array::TimeDate(_) => Array::TimeDate(Box::new([])),
598            #[cfg(feature = "with-time")]
599            Array::TimeTime(_) => Array::TimeTime(Box::new([])),
600            #[cfg(feature = "with-time")]
601            Array::TimeDateTime(_) => Array::TimeDateTime(Box::new([])),
602            #[cfg(feature = "with-time")]
603            Array::TimeDateTimeWithTimeZone(_) => Array::TimeDateTimeWithTimeZone(Box::new([])),
604            #[cfg(feature = "with-jiff")]
605            Array::JiffDate(_) => Array::JiffDate(Box::new([])),
606            #[cfg(feature = "with-jiff")]
607            Array::JiffTime(_) => Array::JiffTime(Box::new([])),
608            #[cfg(feature = "with-jiff")]
609            Array::JiffDateTime(_) => Array::JiffDateTime(Box::new([])),
610            #[cfg(feature = "with-jiff")]
611            Array::JiffTimestamp(_) => Array::JiffTimestamp(Box::new([])),
612            #[cfg(feature = "with-jiff")]
613            Array::JiffZoned(_) => Array::JiffZoned(Box::new([])),
614            #[cfg(feature = "with-uuid")]
615            Array::Uuid(_) => Array::Uuid(Box::new([])),
616            #[cfg(feature = "with-rust_decimal")]
617            Array::Decimal(_) => Array::Decimal(Box::new([])),
618            #[cfg(feature = "with-bigdecimal")]
619            Array::BigDecimal(_) => Array::BigDecimal(Box::new([])),
620            #[cfg(feature = "with-ipnetwork")]
621            Array::IpNetwork(_) => Array::IpNetwork(Box::new([])),
622            #[cfg(feature = "with-mac_address")]
623            Array::MacAddress(_) => Array::MacAddress(Box::new([])),
624            Array::Null(ty) => Array::Null(ty.clone()),
625        }
626    }
627}
628
629impl Value {
630    fn into_array_value_vec(self) -> ArrayValueVec {
631        fn to_vec<T>(v: Option<T>) -> Vec<Option<T>> {
632            vec![v]
633        }
634
635        match self {
636            Self::Bool(v) => ArrayValueVec::Bool(to_vec(v)),
637            Self::TinyInt(v) => ArrayValueVec::TinyInt(to_vec(v)),
638            Self::SmallInt(v) => ArrayValueVec::SmallInt(to_vec(v)),
639            Self::Int(v) => ArrayValueVec::Int(to_vec(v)),
640            Self::BigInt(v) => ArrayValueVec::BigInt(to_vec(v)),
641            Self::TinyUnsigned(v) => ArrayValueVec::TinyUnsigned(to_vec(v)),
642            Self::SmallUnsigned(v) => ArrayValueVec::SmallUnsigned(to_vec(v)),
643            Self::Unsigned(v) => ArrayValueVec::Unsigned(to_vec(v)),
644            Self::BigUnsigned(v) => ArrayValueVec::BigUnsigned(to_vec(v)),
645            Self::Float(v) => ArrayValueVec::Float(to_vec(v)),
646            Self::Double(v) => ArrayValueVec::Double(to_vec(v)),
647            Self::String(v) => ArrayValueVec::String(to_vec(v)),
648            Self::Char(v) => ArrayValueVec::Char(to_vec(v)),
649            Self::Enum(v) => ArrayValueVec::Enum(to_vec(v)),
650            Self::Bytes(v) => ArrayValueVec::Bytes(to_vec(v)),
651
652            #[cfg(feature = "with-json")]
653            Self::Json(v) => ArrayValueVec::Json(to_vec(v)),
654
655            #[cfg(feature = "with-chrono")]
656            Self::ChronoDate(v) => ArrayValueVec::ChronoDate(to_vec(v)),
657
658            #[cfg(feature = "with-chrono")]
659            Self::ChronoTime(v) => ArrayValueVec::ChronoTime(to_vec(v)),
660
661            #[cfg(feature = "with-chrono")]
662            Self::ChronoDateTime(v) => ArrayValueVec::ChronoDateTime(to_vec(v)),
663
664            #[cfg(feature = "with-chrono")]
665            Self::ChronoDateTimeUtc(v) => ArrayValueVec::ChronoDateTimeUtc(to_vec(v)),
666
667            #[cfg(feature = "with-chrono")]
668            Self::ChronoDateTimeLocal(v) => ArrayValueVec::ChronoDateTimeLocal(to_vec(v)),
669
670            #[cfg(feature = "with-chrono")]
671            Self::ChronoDateTimeWithTimeZone(v) => {
672                ArrayValueVec::ChronoDateTimeWithTimeZone(to_vec(v))
673            }
674
675            #[cfg(feature = "with-time")]
676            Self::TimeDate(v) => ArrayValueVec::TimeDate(to_vec(v)),
677
678            #[cfg(feature = "with-time")]
679            Self::TimeTime(v) => ArrayValueVec::TimeTime(to_vec(v)),
680
681            #[cfg(feature = "with-time")]
682            Self::TimeDateTime(v) => ArrayValueVec::TimeDateTime(to_vec(v)),
683
684            #[cfg(feature = "with-time")]
685            Self::TimeDateTimeWithTimeZone(v) => ArrayValueVec::TimeDateTimeWithTimeZone(to_vec(v)),
686
687            #[cfg(feature = "with-jiff")]
688            Self::JiffDate(v) => ArrayValueVec::JiffDate(to_vec(v)),
689
690            #[cfg(feature = "with-jiff")]
691            Self::JiffTime(v) => ArrayValueVec::JiffTime(to_vec(v)),
692
693            #[cfg(feature = "with-jiff")]
694            Self::JiffDateTime(v) => ArrayValueVec::JiffDateTime(to_vec(v)),
695
696            #[cfg(feature = "with-jiff")]
697            Self::JiffTimestamp(v) => ArrayValueVec::JiffTimestamp(to_vec(v)),
698
699            #[cfg(feature = "with-jiff")]
700            Self::JiffZoned(v) => ArrayValueVec::JiffZoned(to_vec(v)),
701
702            #[cfg(feature = "with-uuid")]
703            Self::Uuid(v) => ArrayValueVec::Uuid(to_vec(v)),
704
705            #[cfg(feature = "with-rust_decimal")]
706            Self::Decimal(v) => ArrayValueVec::Decimal(to_vec(v)),
707
708            #[cfg(feature = "with-bigdecimal")]
709            Self::BigDecimal(v) => ArrayValueVec::BigDecimal(to_vec(v)),
710
711            #[cfg(feature = "postgres-array")]
712            Self::Array(v) => v.into_array_value_vec(),
713
714            #[cfg(feature = "postgres-vector")]
715            Self::Vector(_) => panic!("Array of Vector is not supported"),
716
717            #[cfg(feature = "with-ipnetwork")]
718            Self::IpNetwork(v) => ArrayValueVec::IpNetwork(to_vec(v)),
719
720            #[cfg(feature = "with-mac_address")]
721            Self::MacAddress(v) => ArrayValueVec::MacAddress(to_vec(v)),
722
723            #[cfg(feature = "postgres-range")]
724            Self::Range(_) => panic!("Array of Vector is not supported"),
725        }
726    }
727}
728
729impl ArrayValueVec {
730    pub fn push(&mut self, v: Value) {
731        match self {
732            Self::Bool(a) => a.push(v.unwrap()),
733            Self::TinyInt(a) => a.push(v.unwrap()),
734            Self::SmallInt(a) => a.push(v.unwrap()),
735            Self::Int(a) => a.push(v.unwrap()),
736            Self::BigInt(a) => a.push(v.unwrap()),
737            Self::TinyUnsigned(a) => a.push(v.unwrap()),
738            Self::SmallUnsigned(a) => a.push(v.unwrap()),
739            Self::Unsigned(a) => a.push(v.unwrap()),
740            Self::BigUnsigned(a) => a.push(v.unwrap()),
741            Self::Float(a) => a.push(v.unwrap()),
742            Self::Double(a) => a.push(v.unwrap()),
743            Self::String(a) => a.push(v.unwrap()),
744            Self::Char(a) => a.push(v.unwrap()),
745            Self::Bytes(a) => a.push(v.unwrap()),
746            Self::Enum(a) => a.push(match v {
747                Value::Enum(v) => v,
748                _ => panic!("Not Enum"),
749            }),
750            #[cfg(feature = "with-json")]
751            Self::Json(a) => a.push(v.unwrap()),
752            #[cfg(feature = "with-chrono")]
753            Self::ChronoDate(a) => a.push(v.unwrap()),
754            #[cfg(feature = "with-chrono")]
755            Self::ChronoTime(a) => a.push(v.unwrap()),
756            #[cfg(feature = "with-chrono")]
757            Self::ChronoDateTime(a) => a.push(v.unwrap()),
758            #[cfg(feature = "with-chrono")]
759            Self::ChronoDateTimeUtc(a) => a.push(v.unwrap()),
760            #[cfg(feature = "with-chrono")]
761            Self::ChronoDateTimeLocal(a) => a.push(v.unwrap()),
762            #[cfg(feature = "with-chrono")]
763            Self::ChronoDateTimeWithTimeZone(a) => a.push(v.unwrap()),
764            #[cfg(feature = "with-time")]
765            Self::TimeDate(a) => a.push(v.unwrap()),
766            #[cfg(feature = "with-time")]
767            Self::TimeTime(a) => a.push(v.unwrap()),
768            #[cfg(feature = "with-time")]
769            Self::TimeDateTime(a) => a.push(v.unwrap()),
770            #[cfg(feature = "with-time")]
771            Self::TimeDateTimeWithTimeZone(a) => a.push(v.unwrap()),
772            #[cfg(feature = "with-jiff")]
773            Self::JiffDate(a) => a.push(v.unwrap()),
774            #[cfg(feature = "with-jiff")]
775            Self::JiffTime(a) => a.push(v.unwrap()),
776            #[cfg(feature = "with-jiff")]
777            Self::JiffDateTime(a) => a.push(v.unwrap()),
778            #[cfg(feature = "with-jiff")]
779            Self::JiffTimestamp(a) => a.push(v.unwrap()),
780            #[cfg(feature = "with-jiff")]
781            Self::JiffZoned(a) => a.push(v.unwrap()),
782            #[cfg(feature = "with-uuid")]
783            Self::Uuid(a) => a.push(v.unwrap()),
784            #[cfg(feature = "with-rust_decimal")]
785            Self::Decimal(a) => a.push(v.unwrap()),
786            #[cfg(feature = "with-bigdecimal")]
787            Self::BigDecimal(a) => a.push(v.unwrap()),
788            #[cfg(feature = "with-ipnetwork")]
789            Self::IpNetwork(a) => a.push(v.unwrap()),
790            #[cfg(feature = "with-mac_address")]
791            Self::MacAddress(a) => a.push(v.unwrap()),
792        }
793    }
794
795    pub fn into_array(self) -> Array {
796        match self {
797            Self::Bool(a) => Array::Bool(a.into()),
798            Self::TinyInt(a) => Array::TinyInt(a.into()),
799            Self::SmallInt(a) => Array::SmallInt(a.into()),
800            Self::Int(a) => Array::Int(a.into()),
801            Self::BigInt(a) => Array::BigInt(a.into()),
802            Self::TinyUnsigned(a) => Array::TinyUnsigned(a.into()),
803            Self::SmallUnsigned(a) => Array::SmallUnsigned(a.into()),
804            Self::Unsigned(a) => Array::Unsigned(a.into()),
805            Self::BigUnsigned(a) => Array::BigUnsigned(a.into()),
806            Self::Float(a) => Array::Float(a.into()),
807            Self::Double(a) => Array::Double(a.into()),
808            Self::String(a) => Array::String(a.into()),
809            Self::Char(a) => Array::Char(a.into()),
810            Self::Bytes(a) => Array::Bytes(a.into()),
811            Self::Enum(a) => Array::Enum(Box::new((
812                a.first()
813                    .expect("Array empty")
814                    .as_ref()
815                    .unwrap()
816                    .type_name
817                    .as_ref()
818                    .expect("No type_name?")
819                    .clone(),
820                a.into(),
821            ))),
822            #[cfg(feature = "with-json")]
823            Self::Json(a) => Array::Json(a.into()),
824            #[cfg(feature = "with-chrono")]
825            Self::ChronoDate(a) => Array::ChronoDate(a.into()),
826            #[cfg(feature = "with-chrono")]
827            Self::ChronoTime(a) => Array::ChronoTime(a.into()),
828            #[cfg(feature = "with-chrono")]
829            Self::ChronoDateTime(a) => Array::ChronoDateTime(a.into()),
830            #[cfg(feature = "with-chrono")]
831            Self::ChronoDateTimeUtc(a) => Array::ChronoDateTimeUtc(a.into()),
832            #[cfg(feature = "with-chrono")]
833            Self::ChronoDateTimeLocal(a) => Array::ChronoDateTimeLocal(a.into()),
834            #[cfg(feature = "with-chrono")]
835            Self::ChronoDateTimeWithTimeZone(a) => Array::ChronoDateTimeWithTimeZone(a.into()),
836            #[cfg(feature = "with-time")]
837            Self::TimeDate(a) => Array::TimeDate(a.into()),
838            #[cfg(feature = "with-time")]
839            Self::TimeTime(a) => Array::TimeTime(a.into()),
840            #[cfg(feature = "with-time")]
841            Self::TimeDateTime(a) => Array::TimeDateTime(a.into()),
842            #[cfg(feature = "with-time")]
843            Self::TimeDateTimeWithTimeZone(a) => Array::TimeDateTimeWithTimeZone(a.into()),
844            #[cfg(feature = "with-jiff")]
845            Self::JiffDate(a) => Array::JiffDate(a.into()),
846            #[cfg(feature = "with-jiff")]
847            Self::JiffTime(a) => Array::JiffTime(a.into()),
848            #[cfg(feature = "with-jiff")]
849            Self::JiffDateTime(a) => Array::JiffDateTime(a.into()),
850            #[cfg(feature = "with-jiff")]
851            Self::JiffTimestamp(a) => Array::JiffTimestamp(a.into()),
852            #[cfg(feature = "with-jiff")]
853            Self::JiffZoned(a) => Array::JiffZoned(a.into()),
854            #[cfg(feature = "with-uuid")]
855            Self::Uuid(a) => Array::Uuid(a.into()),
856            #[cfg(feature = "with-rust_decimal")]
857            Self::Decimal(a) => Array::Decimal(a.into()),
858            #[cfg(feature = "with-bigdecimal")]
859            Self::BigDecimal(a) => Array::BigDecimal(a.into()),
860            #[cfg(feature = "with-ipnetwork")]
861            Self::IpNetwork(a) => Array::IpNetwork(a.into()),
862            #[cfg(feature = "with-mac_address")]
863            Self::MacAddress(a) => Array::MacAddress(a.into()),
864        }
865    }
866}
867
868impl From<Array> for Value {
869    fn from(value: Array) -> Self {
870        Value::Array(value)
871    }
872}
873
874impl std::fmt::Debug for ArrayIterValue<'_> {
875    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
876        write!(f, "ArrayIterValue")
877    }
878}
879
880impl Iterator for ArrayIterValue<'_> {
881    type Item = Option<Value>;
882
883    fn next(&mut self) -> Option<Self::Item> {
884        self.0.next()
885    }
886}
887
888/// Trait for custom types that can be used as PostgreSQL array elements.
889///
890/// When implemented, SeaQuery will provide:
891/// - `ValueType` for `Vec<T>` and `Vec<Option<T>>`
892/// - `From` implementations for `Vec<T>`, `Vec<Option<T>>`, `Box<[T]>`, `Box<[Option<T>]>`, `[T; N]`, and
893///   `[Option<T>; N]` into `Value` and `Array`
894pub trait ArrayElement: Sized {
895    /// The underlying element type stored in the array.
896    ///
897    /// Usually this is a built-in type like `String`, `i32`, `Uuid`, ...
898    type ArrayValueType: ArrayValue;
899
900    /// Convert self into the underlying array element type.
901    fn into_array_value(self) -> Self::ArrayValueType;
902
903    /// Convert from a Value to `Vec<Option<Self>>`
904    fn try_from_value(v: Value) -> Result<Vec<Option<Self>>, ValueTypeErr>;
905}
906
907/// Internal helper trait used by [`ArrayElement`] to build [`Array`] without specialization.
908///
909/// This trait is sealed and not intended to be implemented by downstream crates. To support a
910/// custom array element type, implement [`ArrayElement`] and set `ArrayValueType` to one of the
911/// built-in array value types supported by SeaQuery.
912pub trait ArrayValue: crate::sealed::Sealed + Sized {
913    fn array_type() -> ArrayType;
914    #[doc(hidden)]
915    fn into_array(iter: impl IntoIterator<Item = Option<Self>>) -> Array;
916}
917
918impl<T: ArrayElement + ValueType> ValueType for Vec<Option<T>> {
919    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
920        T::try_from_value(v)
921    }
922
923    fn type_name() -> String {
924        format!("Vec<Option<{}>>", T::type_name())
925    }
926
927    fn array_type() -> ArrayType {
928        T::ArrayValueType::array_type()
929    }
930
931    fn column_type() -> ColumnType {
932        ColumnType::Array(RcOrArc::new(T::column_type()))
933    }
934}
935
936impl<T: ArrayElement + ValueType> ValueType for Vec<T> {
937    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
938        let vec_opt = T::try_from_value(v)?;
939        vec_opt
940            .into_iter()
941            .map(|opt| opt.ok_or(ValueTypeErr))
942            .collect()
943    }
944
945    fn type_name() -> String {
946        format!("Vec<{}>", T::type_name())
947    }
948
949    fn array_type() -> ArrayType {
950        T::ArrayValueType::array_type()
951    }
952
953    fn column_type() -> ColumnType {
954        ColumnType::Array(RcOrArc::new(T::column_type()))
955    }
956}
957
958impl<T> From<Vec<T>> for Value
959where
960    T: ArrayElement,
961{
962    fn from(vec: Vec<T>) -> Value {
963        Array::from(vec).into()
964    }
965}
966
967impl<T> From<Vec<Option<T>>> for Value
968where
969    T: ArrayElement,
970{
971    fn from(vec: Vec<Option<T>>) -> Value {
972        Array::from(vec).into()
973    }
974}
975
976impl<T> From<Box<[T]>> for Value
977where
978    T: ArrayElement,
979{
980    fn from(vec: Box<[T]>) -> Value {
981        Array::from(vec).into()
982    }
983}
984
985impl<T> From<Box<[Option<T>]>> for Value
986where
987    T: ArrayElement,
988{
989    fn from(vec: Box<[Option<T>]>) -> Value {
990        Array::from(vec).into()
991    }
992}
993
994impl<T, const N: usize> From<[T; N]> for Value
995where
996    T: ArrayElement,
997{
998    fn from(x: [T; N]) -> Value {
999        let iter = x.into_iter().map(|item| item.into_array_value()).map(Some);
1000        ArrayValue::into_array(iter).into()
1001    }
1002}
1003
1004impl<T, const N: usize> From<[Option<T>; N]> for Value
1005where
1006    T: ArrayElement,
1007{
1008    fn from(x: [Option<T>; N]) -> Value {
1009        let iter = x
1010            .into_iter()
1011            .map(|opt| opt.map(|item| item.into_array_value()));
1012        ArrayValue::into_array(iter).into()
1013    }
1014}
1015
1016impl<T> From<Vec<T>> for Array
1017where
1018    T: ArrayElement,
1019{
1020    fn from(vec: Vec<T>) -> Array {
1021        let converted = vec.into_iter().map(|x| x.into_array_value()).map(Some);
1022        ArrayValue::into_array(converted)
1023    }
1024}
1025
1026impl<T> From<Vec<Option<T>>> for Array
1027where
1028    T: ArrayElement,
1029{
1030    fn from(vec: Vec<Option<T>>) -> Array {
1031        let converted = vec.into_iter().map(|opt| opt.map(|e| e.into_array_value()));
1032        ArrayValue::into_array(converted)
1033    }
1034}
1035
1036impl<T> From<Box<[T]>> for Array
1037where
1038    T: ArrayElement,
1039{
1040    fn from(slice: Box<[T]>) -> Array {
1041        ArrayValue::into_array(slice.into_iter().map(|x| x.into_array_value()).map(Some))
1042    }
1043}
1044
1045impl<T> From<Box<[Option<T>]>> for Array
1046where
1047    T: ArrayElement,
1048{
1049    fn from(slice: Box<[Option<T>]>) -> Array {
1050        let converted = slice
1051            .into_iter()
1052            .map(|opt| opt.map(|e| e.into_array_value()));
1053
1054        ArrayValue::into_array(converted)
1055    }
1056}
1057
1058impl<T, const N: usize> From<[T; N]> for Array
1059where
1060    T: ArrayElement,
1061{
1062    fn from(x: [T; N]) -> Array {
1063        let iter = x.into_iter().map(|item| item.into_array_value()).map(Some);
1064        ArrayValue::into_array(iter)
1065    }
1066}
1067
1068impl<T, const N: usize> From<[Option<T>; N]> for Array
1069where
1070    T: ArrayElement,
1071{
1072    fn from(x: [Option<T>; N]) -> Array {
1073        let iter = x
1074            .into_iter()
1075            .map(|opt| opt.map(|item| item.into_array_value()));
1076        ArrayValue::into_array(iter)
1077    }
1078}
1079
1080impl<T> std::iter::FromIterator<T> for Array
1081where
1082    T: ArrayElement,
1083{
1084    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1085        let iter = iter
1086            .into_iter()
1087            .map(|item| item.into_array_value())
1088            .map(Some);
1089        ArrayValue::into_array(iter)
1090    }
1091}
1092
1093impl<T> std::iter::FromIterator<Option<T>> for Array
1094where
1095    T: ArrayElement,
1096{
1097    fn from_iter<I: IntoIterator<Item = Option<T>>>(iter: I) -> Self {
1098        let iter = iter
1099            .into_iter()
1100            .map(|opt| opt.map(|item| item.into_array_value()));
1101        ArrayValue::into_array(iter)
1102    }
1103}
1104
1105impl From<Vec<Value>> for Array {
1106    fn from(values: Vec<Value>) -> Self {
1107        let mut values = values.into_iter();
1108        let mut arr = match values.next() {
1109            Some(value) => value.into_array_value_vec(),
1110            None => return Array::Null(ArrayType::Int), // FIXME
1111        };
1112
1113        for value in values {
1114            arr.push(value);
1115        }
1116
1117        arr.into_array()
1118    }
1119}
1120
1121#[cfg(test)]
1122mod test {
1123    use super::*;
1124
1125    #[test]
1126    fn test_array_value() {
1127        let mut values: Vec<Value> = Vec::new();
1128        values.push(1i32.into());
1129        values.push(2i32.into());
1130        values.push(3i32.into());
1131        let array = Value::Array(values.into());
1132        assert_eq!(
1133            format!("{array:?}"),
1134            "Array(Int([Some(1), Some(2), Some(3)]))"
1135        );
1136        assert_eq!(array, Value::from(vec![1i32, 2, 3]));
1137    }
1138}