1use super::*;
2use crate::RcOrArc;
3#[cfg(feature = "with-json")]
4use crate::backend::ValueEncoder;
5use std::sync::Arc;
6
7type EnumArray = Box<(Arc<str>, Box<[Option<Arc<Enum>>]>)>;
8
9#[derive(Debug, Clone)]
10#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum Array {
13 Bool(Box<[Option<bool>]>),
14 TinyInt(Box<[Option<i8>]>),
15 SmallInt(Box<[Option<i16>]>),
16 Int(Box<[Option<i32>]>),
17 BigInt(Box<[Option<i64>]>),
18 TinyUnsigned(Box<[Option<u8>]>),
19 SmallUnsigned(Box<[Option<u16>]>),
20 Unsigned(Box<[Option<u32>]>),
21 BigUnsigned(Box<[Option<u64>]>),
22 Float(Box<[Option<f32>]>),
23 Double(Box<[Option<f64>]>),
24 String(Box<[Option<String>]>),
25 Char(Box<[Option<char>]>),
26 Bytes(Box<[Option<Vec<u8>>]>),
27 Enum(EnumArray),
28 #[cfg(feature = "with-json")]
29 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
30 Json(Box<[Option<Json>]>),
31 #[cfg(feature = "with-chrono")]
32 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
33 ChronoDate(Box<[Option<NaiveDate>]>),
34 #[cfg(feature = "with-chrono")]
35 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
36 ChronoTime(Box<[Option<NaiveTime>]>),
37 #[cfg(feature = "with-chrono")]
38 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
39 ChronoDateTime(Box<[Option<NaiveDateTime>]>),
40 #[cfg(feature = "with-chrono")]
41 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
42 ChronoDateTimeUtc(Box<[Option<DateTime<Utc>>]>),
43 #[cfg(feature = "with-chrono")]
44 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
45 ChronoDateTimeLocal(Box<[Option<DateTime<Local>>]>),
46 #[cfg(feature = "with-chrono")]
47 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
48 ChronoDateTimeWithTimeZone(Box<[Option<DateTime<FixedOffset>>]>),
49 #[cfg(feature = "with-time")]
50 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
51 TimeDate(Box<[Option<time::Date>]>),
52 #[cfg(feature = "with-time")]
53 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
54 TimeTime(Box<[Option<time::Time>]>),
55 #[cfg(feature = "with-time")]
56 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
57 TimeDateTime(Box<[Option<PrimitiveDateTime>]>),
58 #[cfg(feature = "with-time")]
59 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
60 TimeDateTimeWithTimeZone(Box<[Option<OffsetDateTime>]>),
61 #[cfg(feature = "with-jiff")]
62 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
63 JiffDate(Box<[Option<jiff::civil::Date>]>),
64 #[cfg(feature = "with-jiff")]
65 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
66 JiffTime(Box<[Option<jiff::civil::Time>]>),
67 #[cfg(feature = "with-jiff")]
68 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
69 JiffDateTime(Box<[Option<jiff::civil::DateTime>]>),
70 #[cfg(feature = "with-jiff")]
71 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
72 JiffTimestamp(Box<[Option<Timestamp>]>),
73 #[cfg(feature = "with-jiff")]
74 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
75 JiffZoned(Box<[Option<Zoned>]>),
76 #[cfg(feature = "with-uuid")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
78 Uuid(Box<[Option<Uuid>]>),
79 #[cfg(feature = "with-rust_decimal")]
80 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
81 Decimal(Box<[Option<Decimal>]>),
82 #[cfg(feature = "with-bigdecimal")]
83 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
84 BigDecimal(Box<[Option<BigDecimal>]>),
85 #[cfg(feature = "with-ipnetwork")]
86 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
87 IpNetwork(Box<[Option<IpNetwork>]>),
88 #[cfg(feature = "with-mac_address")]
89 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
90 MacAddress(Box<[Option<MacAddress>]>),
91 Null(ArrayType),
92}
93
94impl Array {
95 pub fn array_type(&self) -> ArrayType {
96 match self {
97 Array::Bool(_) => ArrayType::Bool,
98 Array::TinyInt(_) => ArrayType::TinyInt,
99 Array::SmallInt(_) => ArrayType::SmallInt,
100 Array::Int(_) => ArrayType::Int,
101 Array::BigInt(_) => ArrayType::BigInt,
102 Array::TinyUnsigned(_) => ArrayType::TinyUnsigned,
103 Array::SmallUnsigned(_) => ArrayType::SmallUnsigned,
104 Array::Unsigned(_) => ArrayType::Unsigned,
105 Array::BigUnsigned(_) => ArrayType::BigUnsigned,
106 Array::Float(_) => ArrayType::Float,
107 Array::Double(_) => ArrayType::Double,
108 Array::String(_) => ArrayType::String,
109 Array::Char(_) => ArrayType::Char,
110 Array::Bytes(_) => ArrayType::Bytes,
111 Array::Enum(boxed) => ArrayType::Enum(boxed.as_ref().0.clone()),
112 #[cfg(feature = "with-json")]
113 Array::Json(_) => ArrayType::Json,
114 #[cfg(feature = "with-chrono")]
115 Array::ChronoDate(_) => ArrayType::ChronoDate,
116 #[cfg(feature = "with-chrono")]
117 Array::ChronoTime(_) => ArrayType::ChronoTime,
118 #[cfg(feature = "with-chrono")]
119 Array::ChronoDateTime(_) => ArrayType::ChronoDateTime,
120 #[cfg(feature = "with-chrono")]
121 Array::ChronoDateTimeUtc(_) => ArrayType::ChronoDateTimeUtc,
122 #[cfg(feature = "with-chrono")]
123 Array::ChronoDateTimeLocal(_) => ArrayType::ChronoDateTimeLocal,
124 #[cfg(feature = "with-chrono")]
125 Array::ChronoDateTimeWithTimeZone(_) => ArrayType::ChronoDateTimeWithTimeZone,
126 #[cfg(feature = "with-time")]
127 Array::TimeDate(_) => ArrayType::TimeDate,
128 #[cfg(feature = "with-time")]
129 Array::TimeTime(_) => ArrayType::TimeTime,
130 #[cfg(feature = "with-time")]
131 Array::TimeDateTime(_) => ArrayType::TimeDateTime,
132 #[cfg(feature = "with-time")]
133 Array::TimeDateTimeWithTimeZone(_) => ArrayType::TimeDateTimeWithTimeZone,
134 #[cfg(feature = "with-jiff")]
135 Array::JiffDate(_) => ArrayType::JiffDate,
136 #[cfg(feature = "with-jiff")]
137 Array::JiffTime(_) => ArrayType::JiffTime,
138 #[cfg(feature = "with-jiff")]
139 Array::JiffDateTime(_) => ArrayType::JiffDateTime,
140 #[cfg(feature = "with-jiff")]
141 Array::JiffTimestamp(_) => ArrayType::JiffTimestamp,
142 #[cfg(feature = "with-jiff")]
143 Array::JiffZoned(_) => ArrayType::JiffZoned,
144 #[cfg(feature = "with-uuid")]
145 Array::Uuid(_) => ArrayType::Uuid,
146 #[cfg(feature = "with-rust_decimal")]
147 Array::Decimal(_) => ArrayType::Decimal,
148 #[cfg(feature = "with-bigdecimal")]
149 Array::BigDecimal(_) => ArrayType::BigDecimal,
150 #[cfg(feature = "with-ipnetwork")]
151 Array::IpNetwork(_) => ArrayType::IpNetwork,
152 #[cfg(feature = "with-mac_address")]
153 Array::MacAddress(_) => ArrayType::MacAddress,
154 Array::Null(ty) => ty.clone(),
155 }
156 }
157
158 pub fn is_null(&self) -> bool {
159 matches!(self, Array::Null(_))
160 }
161
162 pub fn is_empty(&self) -> bool {
163 match self {
164 Array::Bool(v) => v.is_empty(),
165 Array::TinyInt(v) => v.is_empty(),
166 Array::SmallInt(v) => v.is_empty(),
167 Array::Int(v) => v.is_empty(),
168 Array::BigInt(v) => v.is_empty(),
169 Array::TinyUnsigned(v) => v.is_empty(),
170 Array::SmallUnsigned(v) => v.is_empty(),
171 Array::Unsigned(v) => v.is_empty(),
172 Array::BigUnsigned(v) => v.is_empty(),
173 Array::Float(v) => v.is_empty(),
174 Array::Double(v) => v.is_empty(),
175 Array::String(v) => v.is_empty(),
176 Array::Char(v) => v.is_empty(),
177 Array::Bytes(v) => v.is_empty(),
178 Array::Enum(b) => b.as_ref().1.is_empty(),
179 #[cfg(feature = "with-json")]
180 Array::Json(v) => v.is_empty(),
181 #[cfg(feature = "with-chrono")]
182 Array::ChronoDate(v) => v.is_empty(),
183 #[cfg(feature = "with-chrono")]
184 Array::ChronoTime(v) => v.is_empty(),
185 #[cfg(feature = "with-chrono")]
186 Array::ChronoDateTime(v) => v.is_empty(),
187 #[cfg(feature = "with-chrono")]
188 Array::ChronoDateTimeUtc(v) => v.is_empty(),
189 #[cfg(feature = "with-chrono")]
190 Array::ChronoDateTimeLocal(v) => v.is_empty(),
191 #[cfg(feature = "with-chrono")]
192 Array::ChronoDateTimeWithTimeZone(v) => v.is_empty(),
193 #[cfg(feature = "with-time")]
194 Array::TimeDate(v) => v.is_empty(),
195 #[cfg(feature = "with-time")]
196 Array::TimeTime(v) => v.is_empty(),
197 #[cfg(feature = "with-time")]
198 Array::TimeDateTime(v) => v.is_empty(),
199 #[cfg(feature = "with-time")]
200 Array::TimeDateTimeWithTimeZone(v) => v.is_empty(),
201 #[cfg(feature = "with-jiff")]
202 Array::JiffDate(v) => v.is_empty(),
203 #[cfg(feature = "with-jiff")]
204 Array::JiffTime(v) => v.is_empty(),
205 #[cfg(feature = "with-jiff")]
206 Array::JiffDateTime(v) => v.is_empty(),
207 #[cfg(feature = "with-jiff")]
208 Array::JiffTimestamp(v) => v.is_empty(),
209 #[cfg(feature = "with-jiff")]
210 Array::JiffZoned(v) => v.is_empty(),
211 #[cfg(feature = "with-uuid")]
212 Array::Uuid(v) => v.is_empty(),
213 #[cfg(feature = "with-rust_decimal")]
214 Array::Decimal(v) => v.is_empty(),
215 #[cfg(feature = "with-bigdecimal")]
216 Array::BigDecimal(v) => v.is_empty(),
217 #[cfg(feature = "with-ipnetwork")]
218 Array::IpNetwork(v) => v.is_empty(),
219 #[cfg(feature = "with-mac_address")]
220 Array::MacAddress(v) => v.is_empty(),
221 Array::Null(_) => true,
222 }
223 }
224
225 #[cfg(feature = "with-json")]
226 pub(crate) fn to_json_value(&self) -> Json {
227 fn map_slice_of_opts<T, F>(slice: &[Option<T>], mut f: F) -> Json
228 where
229 F: FnMut(&T) -> Json,
230 {
231 slice
232 .iter()
233 .map(|o| match o.as_ref() {
234 Some(v) => f(v),
235 None => Json::Null,
236 })
237 .collect()
238 }
239
240 fn encode_to_string<F>(f: F) -> String
241 where
242 F: FnOnce(&CommonSqlQueryBuilder, &mut String),
243 {
244 let mut s = String::new();
245 let enc = CommonSqlQueryBuilder;
246 f(&enc, &mut s);
247 s
248 }
249
250 match self {
251 Array::Bool(v) => map_slice_of_opts(v, |&b| Json::Bool(b)),
252 Array::TinyInt(v) => map_slice_of_opts(v, |&x| x.into()),
253 Array::SmallInt(v) => map_slice_of_opts(v, |&x| x.into()),
254 Array::Int(v) => map_slice_of_opts(v, |&x| x.into()),
255 Array::BigInt(v) => map_slice_of_opts(v, |&x| x.into()),
256 Array::TinyUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
257 Array::SmallUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
258 Array::Unsigned(v) => map_slice_of_opts(v, |&x| x.into()),
259 Array::BigUnsigned(v) => map_slice_of_opts(v, |&x| x.into()),
260 Array::Float(v) => map_slice_of_opts(v, |&x| x.into()),
261 Array::Double(v) => map_slice_of_opts(v, |&x| x.into()),
262 Array::String(v) => map_slice_of_opts(v, |s| Json::String(s.clone())),
263 Array::Char(v) => map_slice_of_opts(v, |&c| Json::String(c.to_string())),
264 Array::Bytes(v) => map_slice_of_opts(v, |bytes| {
265 Json::String(std::str::from_utf8(bytes).unwrap().to_string())
266 }),
267 Array::Enum(v) => {
268 let (_, arr) = v.as_ref();
269 map_slice_of_opts(arr, |e| Json::String(e.value.to_string()))
270 }
271 #[cfg(feature = "with-json")]
272 Array::Json(v) => map_slice_of_opts(v, |j| j.clone()),
273 #[cfg(feature = "with-chrono")]
274 Array::ChronoDate(v) => map_slice_of_opts(v, |&d| {
275 Json::String(encode_to_string(|enc, buf| enc.write_naive_date_to(buf, d)))
276 }),
277 #[cfg(feature = "with-chrono")]
278 Array::ChronoTime(v) => map_slice_of_opts(v, |&t| {
279 Json::String(encode_to_string(|enc, buf| enc.write_naive_time_to(buf, t)))
280 }),
281 #[cfg(feature = "with-chrono")]
282 Array::ChronoDateTime(v) => map_slice_of_opts(v, |&dt| {
283 Json::String(encode_to_string(|enc, buf| {
284 enc.write_naive_datetime_to(buf, dt)
285 }))
286 }),
287 #[cfg(feature = "with-chrono")]
288 Array::ChronoDateTimeUtc(v) => map_slice_of_opts(v, |dt| {
289 Json::String(encode_to_string(|enc, buf| {
290 enc.write_datetime_utc_to(buf, dt)
291 }))
292 }),
293 #[cfg(feature = "with-chrono")]
294 Array::ChronoDateTimeLocal(v) => map_slice_of_opts(v, |dt| {
295 Json::String(encode_to_string(|enc, buf| {
296 enc.write_datetime_local_to(buf, dt)
297 }))
298 }),
299 #[cfg(feature = "with-chrono")]
300 Array::ChronoDateTimeWithTimeZone(v) => map_slice_of_opts(v, |dt| {
301 Json::String(encode_to_string(|enc, buf| {
302 enc.write_datetime_fixed_to(buf, dt)
303 }))
304 }),
305 #[cfg(feature = "with-time")]
306 Array::TimeDate(v) => map_slice_of_opts(v, |&d| {
307 Json::String(encode_to_string(|enc, buf| enc.write_time_date_to(buf, d)))
308 }),
309 #[cfg(feature = "with-time")]
310 Array::TimeTime(v) => map_slice_of_opts(v, |&t| {
311 Json::String(encode_to_string(|enc, buf| enc.write_time_time_to(buf, t)))
312 }),
313 #[cfg(feature = "with-time")]
314 Array::TimeDateTime(v) => map_slice_of_opts(v, |&dt| {
315 Json::String(encode_to_string(|enc, buf| {
316 enc.write_time_datetime_to(buf, dt)
317 }))
318 }),
319 #[cfg(feature = "with-time")]
320 Array::TimeDateTimeWithTimeZone(v) => map_slice_of_opts(v, |&dt| {
321 Json::String(encode_to_string(|enc, buf| {
322 enc.write_time_datetime_tz_to(buf, dt)
323 }))
324 }),
325 #[cfg(feature = "with-jiff")]
326 Array::JiffDate(v) => map_slice_of_opts(v, |&d| {
327 Json::String(encode_to_string(|enc, buf| enc.write_jiff_date_to(buf, d)))
328 }),
329 #[cfg(feature = "with-jiff")]
330 Array::JiffTime(v) => map_slice_of_opts(v, |&t| {
331 Json::String(encode_to_string(|enc, buf| enc.write_jiff_time_to(buf, t)))
332 }),
333 #[cfg(feature = "with-jiff")]
334 Array::JiffDateTime(v) => map_slice_of_opts(v, |&dt| {
335 Json::String(encode_to_string(|enc, buf| {
336 enc.write_jiff_datetime_to(buf, dt)
337 }))
338 }),
339 #[cfg(feature = "with-jiff")]
340 Array::JiffTimestamp(v) => map_slice_of_opts(v, |&ts| {
341 Json::String(encode_to_string(|enc, buf| {
342 enc.write_jiff_timestamp_to(buf, ts)
343 }))
344 }),
345 #[cfg(feature = "with-jiff")]
346 Array::JiffZoned(v) => map_slice_of_opts(v, |z| {
347 Json::String(encode_to_string(|enc, buf| enc.write_jiff_zoned_to(buf, z)))
348 }),
349 #[cfg(feature = "with-uuid")]
350 Array::Uuid(v) => map_slice_of_opts(v, |&u| Json::String(u.to_string())),
351 #[cfg(feature = "with-rust_decimal")]
352 Array::Decimal(v) => map_slice_of_opts(v, |&d| {
353 use rust_decimal::prelude::ToPrimitive;
354 Json::Number(serde_json::Number::from_f64(d.to_f64().unwrap()).unwrap())
355 }),
356 #[cfg(feature = "with-bigdecimal")]
357 Array::BigDecimal(v) => map_slice_of_opts(v, |bd| {
358 use bigdecimal::ToPrimitive;
359 Json::Number(serde_json::Number::from_f64(bd.to_f64().unwrap()).unwrap())
360 }),
361 #[cfg(feature = "with-ipnetwork")]
362 Array::IpNetwork(v) => map_slice_of_opts(v, |&ip| {
363 Json::String(encode_to_string(|enc, buf| enc.write_ipnetwork_to(buf, ip)))
364 }),
365 #[cfg(feature = "with-mac_address")]
366 Array::MacAddress(v) => map_slice_of_opts(v, |&mac| {
367 Json::String(encode_to_string(|enc, buf| {
368 enc.write_mac_address_to(buf, mac)
369 }))
370 }),
371 Array::Null(_) => Json::Null,
372 }
373 }
374
375 pub fn dummy_value(&self) -> Self {
376 match self {
377 Array::Bool(_) => Array::Bool(Box::new([])),
378 Array::TinyInt(_) => Array::TinyInt(Box::new([])),
379 Array::SmallInt(_) => Array::SmallInt(Box::new([])),
380 Array::Int(_) => Array::Int(Box::new([])),
381 Array::BigInt(_) => Array::BigInt(Box::new([])),
382 Array::TinyUnsigned(_) => Array::TinyUnsigned(Box::new([])),
383 Array::SmallUnsigned(_) => Array::SmallUnsigned(Box::new([])),
384 Array::Unsigned(_) => Array::Unsigned(Box::new([])),
385 Array::BigUnsigned(_) => Array::BigUnsigned(Box::new([])),
386 Array::Float(_) => Array::Float(Box::new([])),
387 Array::Double(_) => Array::Double(Box::new([])),
388 Array::String(_) => Array::String(Box::new([])),
389 Array::Char(_) => Array::Char(Box::new([])),
390 Array::Bytes(_) => Array::Bytes(Box::new([])),
391 Array::Enum(val) => {
392 let val = val.as_ref();
393 Array::Enum(Box::new((val.0.clone(), Box::new([]))))
394 }
395 #[cfg(feature = "with-json")]
396 Array::Json(_) => Array::Json(Box::new([])),
397 #[cfg(feature = "with-chrono")]
398 Array::ChronoDate(_) => Array::ChronoDate(Box::new([])),
399 #[cfg(feature = "with-chrono")]
400 Array::ChronoTime(_) => Array::ChronoTime(Box::new([])),
401 #[cfg(feature = "with-chrono")]
402 Array::ChronoDateTime(_) => Array::ChronoDateTime(Box::new([])),
403 #[cfg(feature = "with-chrono")]
404 Array::ChronoDateTimeUtc(_) => Array::ChronoDateTimeUtc(Box::new([])),
405 #[cfg(feature = "with-chrono")]
406 Array::ChronoDateTimeLocal(_) => Array::ChronoDateTimeLocal(Box::new([])),
407 #[cfg(feature = "with-chrono")]
408 Array::ChronoDateTimeWithTimeZone(_) => Array::ChronoDateTimeWithTimeZone(Box::new([])),
409 #[cfg(feature = "with-time")]
410 Array::TimeDate(_) => Array::TimeDate(Box::new([])),
411 #[cfg(feature = "with-time")]
412 Array::TimeTime(_) => Array::TimeTime(Box::new([])),
413 #[cfg(feature = "with-time")]
414 Array::TimeDateTime(_) => Array::TimeDateTime(Box::new([])),
415 #[cfg(feature = "with-time")]
416 Array::TimeDateTimeWithTimeZone(_) => Array::TimeDateTimeWithTimeZone(Box::new([])),
417 #[cfg(feature = "with-jiff")]
418 Array::JiffDate(_) => Array::JiffDate(Box::new([])),
419 #[cfg(feature = "with-jiff")]
420 Array::JiffTime(_) => Array::JiffTime(Box::new([])),
421 #[cfg(feature = "with-jiff")]
422 Array::JiffDateTime(_) => Array::JiffDateTime(Box::new([])),
423 #[cfg(feature = "with-jiff")]
424 Array::JiffTimestamp(_) => Array::JiffTimestamp(Box::new([])),
425 #[cfg(feature = "with-jiff")]
426 Array::JiffZoned(_) => Array::JiffZoned(Box::new([])),
427 #[cfg(feature = "with-uuid")]
428 Array::Uuid(_) => Array::Uuid(Box::new([])),
429 #[cfg(feature = "with-rust_decimal")]
430 Array::Decimal(_) => Array::Decimal(Box::new([])),
431 #[cfg(feature = "with-bigdecimal")]
432 Array::BigDecimal(_) => Array::BigDecimal(Box::new([])),
433 #[cfg(feature = "with-ipnetwork")]
434 Array::IpNetwork(_) => Array::IpNetwork(Box::new([])),
435 #[cfg(feature = "with-mac_address")]
436 Array::MacAddress(_) => Array::MacAddress(Box::new([])),
437 Array::Null(ty) => Array::Null(ty.clone()),
438 }
439 }
440}
441
442impl From<Array> for Value {
443 fn from(value: Array) -> Self {
444 Value::Array(value)
445 }
446}
447
448pub trait ArrayElement: Sized {
455 type ArrayValueType: ArrayValue;
459
460 fn into_array_value(self) -> Self::ArrayValueType;
462
463 fn try_from_value(v: Value) -> Result<Vec<Option<Self>>, ValueTypeErr>;
465}
466
467pub trait ArrayValue: Sized {
471 #[doc(hidden)]
472 fn vec_opt_into_array(vec: Vec<Option<Self>>) -> Array;
473 #[doc(hidden)]
474 fn vec_into_array(vec: Vec<Self>) -> Array;
475}
476
477impl<T> ArrayValue for T
478where
479 Vec<Option<T>>: Into<Array>,
480{
481 fn vec_opt_into_array(vec: Vec<Option<Self>>) -> Array {
482 vec.into()
483 }
484
485 fn vec_into_array(vec: Vec<Self>) -> Array {
486 let vec: Vec<_> = vec.into_iter().map(Some).collect();
487 vec.into()
488 }
489}
490
491impl<T: ArrayElement + ValueType> ValueType for Vec<Option<T>> {
492 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
493 T::try_from_value(v)
494 }
495
496 fn type_name() -> String {
497 format!("Vec<Option<{}>>", T::type_name())
498 }
499
500 fn array_type() -> ArrayType {
501 unimplemented!()
502 }
503
504 fn column_type() -> ColumnType {
505 ColumnType::Array(RcOrArc::new(T::column_type()))
506 }
507}
508
509impl<T: ArrayElement + ValueType> ValueType for Vec<T> {
510 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
511 let vec_opt = T::try_from_value(v)?;
512 vec_opt
513 .into_iter()
514 .map(|opt| opt.ok_or(ValueTypeErr))
515 .collect()
516 }
517
518 fn type_name() -> String {
519 format!("Vec<{}>", T::type_name())
520 }
521
522 fn array_type() -> ArrayType {
523 unimplemented!()
524 }
525
526 fn column_type() -> ColumnType {
527 ColumnType::Array(RcOrArc::new(T::column_type()))
528 }
529}
530
531impl<T> From<Vec<T>> for Value
532where
533 T: ArrayElement,
534{
535 fn from(vec: Vec<T>) -> Value {
536 Array::from(vec).into()
537 }
538}
539
540impl<T> From<Vec<Option<T>>> for Value
541where
542 T: ArrayElement,
543{
544 fn from(vec: Vec<Option<T>>) -> Value {
545 Array::from(vec).into()
546 }
547}
548
549impl<T> From<Vec<T>> for Array
550where
551 T: ArrayElement,
552{
553 fn from(vec: Vec<T>) -> Array {
554 let converted: Vec<_> = vec.into_iter().map(|x| x.into_array_value()).collect();
555
556 ArrayValue::vec_into_array(converted)
557 }
558}
559
560impl<T> From<Vec<Option<T>>> for Array
561where
562 T: ArrayElement,
563{
564 fn from(vec: Vec<Option<T>>) -> Array {
565 let converted: Vec<Option<T::ArrayValueType>> = vec
566 .into_iter()
567 .map(|opt| opt.map(|e| e.into_array_value()))
568 .collect();
569 ArrayValue::vec_opt_into_array(converted)
570 }
571}
572
573#[cfg(feature = "hashable-value")]
574mod hash {
575 use ordered_float::{FloatCore, OrderedFloat};
576
577 use super::Array;
578
579 #[inline]
580 fn map_option_ordered_float_vec<T>(
581 vec: &[Option<T>],
582 ) -> impl Iterator<Item = Option<OrderedFloat<T>>> + '_
583 where
584 T: FloatCore,
585 {
586 vec.iter().copied().map(|x| x.map(OrderedFloat))
587 }
588
589 #[inline]
590 fn cmp_option_ordered_float_vec<T>(left: &[Option<T>], right: &[Option<T>]) -> bool
591 where
592 T: FloatCore,
593 {
594 map_option_ordered_float_vec(left).eq(map_option_ordered_float_vec(right))
595 }
596
597 impl PartialEq for Array {
598 fn eq(&self, other: &Self) -> bool {
599 match (self, other) {
600 (Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
601 (Self::TinyInt(l0), Self::TinyInt(r0)) => l0 == r0,
602 (Self::SmallInt(l0), Self::SmallInt(r0)) => l0 == r0,
603 (Self::Int(l0), Self::Int(r0)) => l0 == r0,
604 (Self::BigInt(l0), Self::BigInt(r0)) => l0 == r0,
605 (Self::TinyUnsigned(l0), Self::TinyUnsigned(r0)) => l0 == r0,
606 (Self::SmallUnsigned(l0), Self::SmallUnsigned(r0)) => l0 == r0,
607 (Self::Unsigned(l0), Self::Unsigned(r0)) => l0 == r0,
608 (Self::BigUnsigned(l0), Self::BigUnsigned(r0)) => l0 == r0,
609 (Self::Float(l0), Self::Float(r0)) => cmp_option_ordered_float_vec(l0, r0),
610 (Self::Double(l0), Self::Double(r0)) => cmp_option_ordered_float_vec(l0, r0),
611 (Self::String(l0), Self::String(r0)) => l0 == r0,
612 (Self::Char(l0), Self::Char(r0)) => l0 == r0,
613 (Self::Bytes(l0), Self::Bytes(r0)) => l0 == r0,
614 (Self::Enum(l0), Self::Enum(r0)) => l0 == r0,
615 #[cfg(feature = "with-json")]
616 (Self::Json(l0), Self::Json(r0)) => l0 == r0,
617 #[cfg(feature = "with-chrono")]
618 (Self::ChronoDate(l0), Self::ChronoDate(r0)) => l0 == r0,
619 #[cfg(feature = "with-chrono")]
620 (Self::ChronoTime(l0), Self::ChronoTime(r0)) => l0 == r0,
621 #[cfg(feature = "with-chrono")]
622 (Self::ChronoDateTime(l0), Self::ChronoDateTime(r0)) => l0 == r0,
623 #[cfg(feature = "with-chrono")]
624 (Self::ChronoDateTimeUtc(l0), Self::ChronoDateTimeUtc(r0)) => l0 == r0,
625 #[cfg(feature = "with-chrono")]
626 (Self::ChronoDateTimeLocal(l0), Self::ChronoDateTimeLocal(r0)) => l0 == r0,
627 #[cfg(feature = "with-chrono")]
628 (Self::ChronoDateTimeWithTimeZone(l0), Self::ChronoDateTimeWithTimeZone(r0)) => {
629 l0 == r0
630 }
631 #[cfg(feature = "with-time")]
632 (Self::TimeDate(l0), Self::TimeDate(r0)) => l0 == r0,
633 #[cfg(feature = "with-time")]
634 (Self::TimeTime(l0), Self::TimeTime(r0)) => l0 == r0,
635 #[cfg(feature = "with-time")]
636 (Self::TimeDateTime(l0), Self::TimeDateTime(r0)) => l0 == r0,
637 #[cfg(feature = "with-time")]
638 (Self::TimeDateTimeWithTimeZone(l0), Self::TimeDateTimeWithTimeZone(r0)) => {
639 l0 == r0
640 }
641 #[cfg(feature = "with-jiff")]
642 (Self::JiffDate(l0), Self::JiffDate(r0)) => l0 == r0,
643 #[cfg(feature = "with-jiff")]
644 (Self::JiffTime(l0), Self::JiffTime(r0)) => l0 == r0,
645 #[cfg(feature = "with-jiff")]
646 (Self::JiffDateTime(l0), Self::JiffDateTime(r0)) => l0 == r0,
647 #[cfg(feature = "with-jiff")]
648 (Self::JiffTimestamp(l0), Self::JiffTimestamp(r0)) => l0 == r0,
649 #[cfg(feature = "with-jiff")]
650 (Self::JiffZoned(l0), Self::JiffZoned(r0)) => l0 == r0,
651 #[cfg(feature = "with-uuid")]
652 (Self::Uuid(l0), Self::Uuid(r0)) => l0 == r0,
653 #[cfg(feature = "with-rust_decimal")]
654 (Self::Decimal(l0), Self::Decimal(r0)) => l0 == r0,
655 #[cfg(feature = "with-bigdecimal")]
656 (Self::BigDecimal(l0), Self::BigDecimal(r0)) => l0 == r0,
657 #[cfg(feature = "with-ipnetwork")]
658 (Self::IpNetwork(l0), Self::IpNetwork(r0)) => l0 == r0,
659 #[cfg(feature = "with-mac_address")]
660 (Self::MacAddress(l0), Self::MacAddress(r0)) => l0 == r0,
661 (Self::Null(l0), Self::Null(r0)) => l0 == r0,
662 _ => false,
663 }
664 }
665 }
666
667 impl Eq for Array {}
668
669 impl std::hash::Hash for Array {
670 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
671 use ordered_float::OrderedFloat;
672
673 std::mem::discriminant(self).hash(state);
674 match self {
675 Array::Bool(items) => items.hash(state),
676 Array::TinyInt(items) => items.hash(state),
677 Array::SmallInt(items) => items.hash(state),
678 Array::Int(items) => items.hash(state),
679 Array::BigInt(items) => items.hash(state),
680 Array::TinyUnsigned(items) => items.hash(state),
681 Array::SmallUnsigned(items) => items.hash(state),
682 Array::Unsigned(items) => items.hash(state),
683 Array::BigUnsigned(items) => items.hash(state),
684 Array::Float(items) => {
685 for x in items.iter() {
686 x.map(OrderedFloat).hash(state)
687 }
688 }
689 Array::Double(items) => {
690 for x in items.iter() {
691 x.map(OrderedFloat).hash(state)
692 }
693 }
694 Array::String(items) => items.hash(state),
695 Array::Char(items) => items.hash(state),
696 Array::Bytes(items) => items.hash(state),
697 Array::Enum(items) => items.hash(state),
698 #[cfg(feature = "with-json")]
699 Array::Json(items) => items.hash(state),
700 #[cfg(feature = "with-chrono")]
701 Array::ChronoDate(items) => items.hash(state),
702 #[cfg(feature = "with-chrono")]
703 Array::ChronoTime(items) => items.hash(state),
704 #[cfg(feature = "with-chrono")]
705 Array::ChronoDateTime(items) => items.hash(state),
706 #[cfg(feature = "with-chrono")]
707 Array::ChronoDateTimeUtc(items) => items.hash(state),
708 #[cfg(feature = "with-chrono")]
709 Array::ChronoDateTimeLocal(items) => items.hash(state),
710 #[cfg(feature = "with-chrono")]
711 Array::ChronoDateTimeWithTimeZone(items) => items.hash(state),
712 #[cfg(feature = "with-time")]
713 Array::TimeDate(items) => items.hash(state),
714 #[cfg(feature = "with-time")]
715 Array::TimeTime(items) => items.hash(state),
716 #[cfg(feature = "with-time")]
717 Array::TimeDateTime(items) => items.hash(state),
718 #[cfg(feature = "with-time")]
719 Array::TimeDateTimeWithTimeZone(items) => items.hash(state),
720 #[cfg(feature = "with-jiff")]
721 Array::JiffDate(items) => items.hash(state),
722 #[cfg(feature = "with-jiff")]
723 Array::JiffTime(items) => items.hash(state),
724 #[cfg(feature = "with-jiff")]
725 Array::JiffDateTime(items) => items.hash(state),
726 #[cfg(feature = "with-jiff")]
727 Array::JiffTimestamp(items) => items.hash(state),
728 #[cfg(feature = "with-jiff")]
729 Array::JiffZoned(items) => items.hash(state),
730 #[cfg(feature = "with-uuid")]
731 Array::Uuid(items) => items.hash(state),
732 #[cfg(feature = "with-rust_decimal")]
733 Array::Decimal(items) => items.hash(state),
734 #[cfg(feature = "with-bigdecimal")]
735 Array::BigDecimal(items) => items.hash(state),
736 #[cfg(feature = "with-ipnetwork")]
737 Array::IpNetwork(items) => items.hash(state),
738 #[cfg(feature = "with-mac_address")]
739 Array::MacAddress(items) => items.hash(state),
740 Array::Null(ty) => ty.hash(state),
741 }
742 }
743 }
744}