1use std::fmt;
21
22use chrono::{TimeZone, Utc};
23use half::f16;
24use num_bigint::{BigInt, Sign};
25use num_traits::Float;
26
27use crate::basic::{ConvertedType, LogicalType, Type as PhysicalType};
28use crate::data_type::{ByteArray, Decimal, Int96};
29use crate::errors::{ParquetError, Result};
30use crate::schema::types::ColumnDescPtr;
31
32#[cfg(any(feature = "json", test))]
33use serde_json::Value;
34
35macro_rules! nyi {
37 ($column_descr:ident, $value:ident) => {{
38 unimplemented!(
39 "Conversion for physical type {}, converted type {}, value {:?}",
40 $column_descr.physical_type(),
41 $column_descr.converted_type(),
42 $value
43 );
44 }};
45}
46
47#[derive(Clone, Debug, PartialEq)]
49pub struct Row {
50 fields: Vec<(String, Field)>,
51}
52
53#[expect(clippy::len_without_is_empty)]
54impl Row {
55 pub fn new(fields: Vec<(String, Field)>) -> Row {
57 Row { fields }
58 }
59
60 pub fn len(&self) -> usize {
62 self.fields.len()
63 }
64
65 pub fn into_columns(self) -> Vec<(String, Field)> {
82 self.fields
83 }
84
85 pub fn get_column_iter(&self) -> RowColumnIter<'_> {
102 RowColumnIter {
103 fields: &self.fields,
104 curr: 0,
105 count: self.fields.len(),
106 }
107 }
108
109 #[cfg(any(feature = "json", test))]
111 pub fn to_json_value(&self) -> Value {
112 Value::Object(
113 self.fields
114 .iter()
115 .map(|(key, field)| (key.to_owned(), field.to_json_value()))
116 .collect(),
117 )
118 }
119}
120
121pub struct RowColumnIter<'a> {
123 fields: &'a Vec<(String, Field)>,
124 curr: usize,
125 count: usize,
126}
127
128impl<'a> Iterator for RowColumnIter<'a> {
129 type Item = (&'a String, &'a Field);
130
131 fn next(&mut self) -> Option<Self::Item> {
132 let idx = self.curr;
133 if idx >= self.count {
134 return None;
135 }
136 self.curr += 1;
137 Some((&self.fields[idx].0, &self.fields[idx].1))
138 }
139}
140
141pub trait RowAccessor {
143 fn is_null(&self, i: usize) -> Result<bool>;
145 fn get_bool(&self, i: usize) -> Result<bool>;
147 fn get_byte(&self, i: usize) -> Result<i8>;
149 fn get_short(&self, i: usize) -> Result<i16>;
151 fn get_int(&self, i: usize) -> Result<i32>;
153 fn get_long(&self, i: usize) -> Result<i64>;
155 fn get_ubyte(&self, i: usize) -> Result<u8>;
157 fn get_ushort(&self, i: usize) -> Result<u16>;
159 fn get_uint(&self, i: usize) -> Result<u32>;
161 fn get_ulong(&self, i: usize) -> Result<u64>;
163 fn get_float16(&self, i: usize) -> Result<f16>;
165 fn get_float(&self, i: usize) -> Result<f32>;
167 fn get_double(&self, i: usize) -> Result<f64>;
169 fn get_timestamp_millis(&self, i: usize) -> Result<i64>;
171 fn get_timestamp_micros(&self, i: usize) -> Result<i64>;
173 fn get_decimal(&self, i: usize) -> Result<&Decimal>;
175 fn get_string(&self, i: usize) -> Result<&String>;
177 fn get_bytes(&self, i: usize) -> Result<&ByteArray>;
179 fn get_group(&self, i: usize) -> Result<&Row>;
181 fn get_list(&self, i: usize) -> Result<&List>;
183 fn get_map(&self, i: usize) -> Result<&Map>;
185}
186
187pub trait RowFormatter {
206 fn fmt(&self, i: usize) -> &dyn fmt::Display;
208}
209
210macro_rules! row_primitive_accessor {
213 ($METHOD:ident, $VARIANT:ident, $TY:ty) => {
214 fn $METHOD(&self, i: usize) -> Result<$TY> {
215 match self.fields.get(i) {
216 Some((_, Field::$VARIANT(v))) => Ok(*v),
217 None => Err(ParquetError::IndexOutOfBound(i, self.fields.len())),
218 _ => Err(general_err!(
219 "Cannot access {} as {}",
220 self.fields[i].1.get_type_name(), stringify!($VARIANT)
222 )),
223 }
224 }
225 };
226}
227
228macro_rules! row_complex_accessor {
231 ($METHOD:ident, $VARIANT:ident, $TY:ty) => {
232 fn $METHOD(&self, i: usize) -> Result<&$TY> {
233 match self.fields.get(i) {
234 Some((_, Field::$VARIANT(v))) => Ok(v),
235 None => Err(ParquetError::IndexOutOfBound(i, self.fields.len())),
236 _ => Err(general_err!(
237 "Cannot access {} as {}",
238 self.fields[i].1.get_type_name(), stringify!($VARIANT)
241 )),
242 }
243 }
244 };
245}
246
247impl RowFormatter for Row {
248 fn fmt(&self, i: usize) -> &dyn fmt::Display {
250 if let Some((_, v)) = self.fields.get(i) {
251 v
252 } else {
253 &"<IndexOutOfBound>"
254 }
255 }
256}
257
258impl RowAccessor for Row {
259 fn is_null(&self, i: usize) -> Result<bool> {
260 match self.fields.get(i) {
261 Some((_, Field::Null)) => Ok(true),
262 None => Err(ParquetError::IndexOutOfBound(i, self.len())),
263 _ => Ok(false),
264 }
265 }
266
267 row_primitive_accessor!(get_bool, Bool, bool);
268
269 row_primitive_accessor!(get_byte, Byte, i8);
270
271 row_primitive_accessor!(get_short, Short, i16);
272
273 row_primitive_accessor!(get_int, Int, i32);
274
275 row_primitive_accessor!(get_long, Long, i64);
276
277 row_primitive_accessor!(get_ubyte, UByte, u8);
278
279 row_primitive_accessor!(get_ushort, UShort, u16);
280
281 row_primitive_accessor!(get_uint, UInt, u32);
282
283 row_primitive_accessor!(get_ulong, ULong, u64);
284
285 row_primitive_accessor!(get_float16, Float16, f16);
286
287 row_primitive_accessor!(get_float, Float, f32);
288
289 row_primitive_accessor!(get_double, Double, f64);
290
291 row_primitive_accessor!(get_timestamp_millis, TimestampMillis, i64);
292
293 row_primitive_accessor!(get_timestamp_micros, TimestampMicros, i64);
294
295 row_complex_accessor!(get_decimal, Decimal, Decimal);
296
297 row_complex_accessor!(get_string, Str, String);
298
299 row_complex_accessor!(get_bytes, Bytes, ByteArray);
300
301 row_complex_accessor!(get_group, Group, Row);
302
303 row_complex_accessor!(get_list, ListInternal, List);
304
305 row_complex_accessor!(get_map, MapInternal, Map);
306}
307
308impl fmt::Display for Row {
309 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
310 write!(f, "{{")?;
311 for (i, (key, value)) in self.fields.iter().enumerate() {
312 key.fmt(f)?;
313 write!(f, ": ")?;
314 value.fmt(f)?;
315 if i < self.fields.len() - 1 {
316 write!(f, ", ")?;
317 }
318 }
319 write!(f, "}}")
320 }
321}
322
323#[derive(Clone, Debug, PartialEq)]
325pub struct List {
326 elements: Vec<Field>,
327}
328
329#[expect(clippy::len_without_is_empty)]
330impl List {
331 pub fn len(&self) -> usize {
333 self.elements.len()
334 }
335
336 pub fn elements(&self) -> &[Field] {
338 self.elements.as_slice()
339 }
340}
341
342#[inline]
344pub fn make_list(elements: Vec<Field>) -> List {
345 List { elements }
346}
347
348pub trait ListAccessor {
351 fn get_bool(&self, i: usize) -> Result<bool>;
353 fn get_byte(&self, i: usize) -> Result<i8>;
355 fn get_short(&self, i: usize) -> Result<i16>;
357 fn get_int(&self, i: usize) -> Result<i32>;
359 fn get_long(&self, i: usize) -> Result<i64>;
361 fn get_ubyte(&self, i: usize) -> Result<u8>;
363 fn get_ushort(&self, i: usize) -> Result<u16>;
365 fn get_uint(&self, i: usize) -> Result<u32>;
367 fn get_ulong(&self, i: usize) -> Result<u64>;
369 fn get_float16(&self, i: usize) -> Result<f16>;
371 fn get_float(&self, i: usize) -> Result<f32>;
373 fn get_double(&self, i: usize) -> Result<f64>;
375 fn get_timestamp_millis(&self, i: usize) -> Result<i64>;
378 fn get_timestamp_micros(&self, i: usize) -> Result<i64>;
381 fn get_decimal(&self, i: usize) -> Result<&Decimal>;
383 fn get_string(&self, i: usize) -> Result<&String>;
385 fn get_bytes(&self, i: usize) -> Result<&ByteArray>;
387 fn get_group(&self, i: usize) -> Result<&Row>;
389 fn get_list(&self, i: usize) -> Result<&List>;
391 fn get_map(&self, i: usize) -> Result<&Map>;
393}
394
395macro_rules! list_primitive_accessor {
398 ($METHOD:ident, $VARIANT:ident, $TY:ty) => {
399 fn $METHOD(&self, i: usize) -> Result<$TY> {
400 match self.elements[i] {
401 Field::$VARIANT(v) => Ok(v),
402 _ => Err(general_err!(
403 "Cannot access {} as {}",
404 self.elements[i].get_type_name(),
405 stringify!($VARIANT)
406 )),
407 }
408 }
409 };
410}
411
412macro_rules! list_complex_accessor {
415 ($METHOD:ident, $VARIANT:ident, $TY:ty) => {
416 fn $METHOD(&self, i: usize) -> Result<&$TY> {
417 match &self.elements[i] {
418 Field::$VARIANT(v) => Ok(&v),
419 _ => Err(general_err!(
420 "Cannot access {} as {}",
421 self.elements[i].get_type_name(),
422 stringify!($VARIANT)
423 )),
424 }
425 }
426 };
427}
428
429impl ListAccessor for List {
430 list_primitive_accessor!(get_bool, Bool, bool);
431
432 list_primitive_accessor!(get_byte, Byte, i8);
433
434 list_primitive_accessor!(get_short, Short, i16);
435
436 list_primitive_accessor!(get_int, Int, i32);
437
438 list_primitive_accessor!(get_long, Long, i64);
439
440 list_primitive_accessor!(get_ubyte, UByte, u8);
441
442 list_primitive_accessor!(get_ushort, UShort, u16);
443
444 list_primitive_accessor!(get_uint, UInt, u32);
445
446 list_primitive_accessor!(get_ulong, ULong, u64);
447
448 list_primitive_accessor!(get_float16, Float16, f16);
449
450 list_primitive_accessor!(get_float, Float, f32);
451
452 list_primitive_accessor!(get_double, Double, f64);
453
454 list_primitive_accessor!(get_timestamp_millis, TimestampMillis, i64);
455
456 list_primitive_accessor!(get_timestamp_micros, TimestampMicros, i64);
457
458 list_complex_accessor!(get_decimal, Decimal, Decimal);
459
460 list_complex_accessor!(get_string, Str, String);
461
462 list_complex_accessor!(get_bytes, Bytes, ByteArray);
463
464 list_complex_accessor!(get_group, Group, Row);
465
466 list_complex_accessor!(get_list, ListInternal, List);
467
468 list_complex_accessor!(get_map, MapInternal, Map);
469}
470
471#[derive(Clone, Debug, PartialEq)]
473pub struct Map {
474 entries: Vec<(Field, Field)>,
475}
476
477#[expect(clippy::len_without_is_empty)]
478impl Map {
479 pub fn len(&self) -> usize {
481 self.entries.len()
482 }
483
484 pub fn entries(&self) -> &[(Field, Field)] {
486 self.entries.as_slice()
487 }
488}
489
490#[inline]
492pub fn make_map(entries: Vec<(Field, Field)>) -> Map {
493 Map { entries }
494}
495
496pub trait MapAccessor {
498 fn get_keys<'a>(&'a self) -> Box<dyn ListAccessor + 'a>;
500 fn get_values<'a>(&'a self) -> Box<dyn ListAccessor + 'a>;
502}
503
504struct MapList<'a> {
505 elements: Vec<&'a Field>,
506}
507
508macro_rules! map_list_primitive_accessor {
511 ($METHOD:ident, $VARIANT:ident, $TY:ty) => {
512 fn $METHOD(&self, i: usize) -> Result<$TY> {
513 match self.elements[i] {
514 Field::$VARIANT(v) => Ok(*v),
515 _ => Err(general_err!(
516 "Cannot access {} as {}",
517 self.elements[i].get_type_name(),
518 stringify!($VARIANT)
519 )),
520 }
521 }
522 };
523}
524
525impl ListAccessor for MapList<'_> {
526 map_list_primitive_accessor!(get_bool, Bool, bool);
527
528 map_list_primitive_accessor!(get_byte, Byte, i8);
529
530 map_list_primitive_accessor!(get_short, Short, i16);
531
532 map_list_primitive_accessor!(get_int, Int, i32);
533
534 map_list_primitive_accessor!(get_long, Long, i64);
535
536 map_list_primitive_accessor!(get_ubyte, UByte, u8);
537
538 map_list_primitive_accessor!(get_ushort, UShort, u16);
539
540 map_list_primitive_accessor!(get_uint, UInt, u32);
541
542 map_list_primitive_accessor!(get_ulong, ULong, u64);
543
544 map_list_primitive_accessor!(get_float16, Float16, f16);
545
546 map_list_primitive_accessor!(get_float, Float, f32);
547
548 map_list_primitive_accessor!(get_double, Double, f64);
549
550 map_list_primitive_accessor!(get_timestamp_millis, TimestampMillis, i64);
551
552 map_list_primitive_accessor!(get_timestamp_micros, TimestampMicros, i64);
553
554 list_complex_accessor!(get_decimal, Decimal, Decimal);
555
556 list_complex_accessor!(get_string, Str, String);
557
558 list_complex_accessor!(get_bytes, Bytes, ByteArray);
559
560 list_complex_accessor!(get_group, Group, Row);
561
562 list_complex_accessor!(get_list, ListInternal, List);
563
564 list_complex_accessor!(get_map, MapInternal, Map);
565}
566
567impl MapAccessor for Map {
568 fn get_keys<'a>(&'a self) -> Box<dyn ListAccessor + 'a> {
569 let map_list = MapList {
570 elements: self.entries.iter().map(|v| &v.0).collect(),
571 };
572 Box::new(map_list)
573 }
574
575 fn get_values<'a>(&'a self) -> Box<dyn ListAccessor + 'a> {
576 let map_list = MapList {
577 elements: self.entries.iter().map(|v| &v.1).collect(),
578 };
579 Box::new(map_list)
580 }
581}
582
583#[derive(Clone, Debug, PartialEq)]
585pub enum Field {
586 Null,
589 Bool(bool),
591 Byte(i8),
593 Short(i16),
595 Int(i32),
597 Long(i64),
599 UByte(u8),
601 UShort(u16),
603 UInt(u32),
605 ULong(u64),
607 Float16(f16),
609 Float(f32),
611 Double(f64),
613 Decimal(Decimal),
615 Str(String),
617 Bytes(ByteArray),
619 Date(i32),
622
623 TimeMillis(i32),
625 TimeMicros(i64),
627
628 TimestampMillis(i64),
630 TimestampMicros(i64),
632
633 Group(Row),
637 ListInternal(List),
639 MapInternal(Map),
641}
642
643impl Field {
644 fn get_type_name(&self) -> &'static str {
646 match *self {
647 Field::Null => "Null",
648 Field::Bool(_) => "Bool",
649 Field::Byte(_) => "Byte",
650 Field::Short(_) => "Short",
651 Field::Int(_) => "Int",
652 Field::Long(_) => "Long",
653 Field::UByte(_) => "UByte",
654 Field::UShort(_) => "UShort",
655 Field::UInt(_) => "UInt",
656 Field::ULong(_) => "ULong",
657 Field::Float16(_) => "Float16",
658 Field::Float(_) => "Float",
659 Field::Double(_) => "Double",
660 Field::Decimal(_) => "Decimal",
661 Field::Date(_) => "Date",
662 Field::Str(_) => "Str",
663 Field::Bytes(_) => "Bytes",
664 Field::TimeMillis(_) => "TimeMillis",
665 Field::TimeMicros(_) => "TimeMicros",
666 Field::TimestampMillis(_) => "TimestampMillis",
667 Field::TimestampMicros(_) => "TimestampMicros",
668 Field::Group(_) => "Group",
669 Field::ListInternal(_) => "ListInternal",
670 Field::MapInternal(_) => "MapInternal",
671 }
672 }
673
674 pub fn is_primitive(&self) -> bool {
676 !matches!(
677 *self,
678 Field::Group(_) | Field::ListInternal(_) | Field::MapInternal(_)
679 )
680 }
681
682 #[inline]
684 pub fn convert_bool(_descr: &ColumnDescPtr, value: bool) -> Self {
685 Field::Bool(value)
686 }
687
688 #[inline]
690 pub fn convert_int32(descr: &ColumnDescPtr, value: i32) -> Self {
691 match descr.converted_type() {
692 ConvertedType::INT_8 => Field::Byte(value as i8),
693 ConvertedType::INT_16 => Field::Short(value as i16),
694 ConvertedType::INT_32 | ConvertedType::NONE => Field::Int(value),
695 ConvertedType::UINT_8 => Field::UByte(value as u8),
696 ConvertedType::UINT_16 => Field::UShort(value as u16),
697 ConvertedType::UINT_32 => Field::UInt(value as u32),
698 ConvertedType::DATE => Field::Date(value),
699 ConvertedType::TIME_MILLIS => Field::TimeMillis(value),
700 ConvertedType::DECIMAL => Field::Decimal(Decimal::from_i32(
701 value,
702 descr.type_precision(),
703 descr.type_scale(),
704 )),
705 _ => nyi!(descr, value),
706 }
707 }
708
709 #[inline]
711 pub fn convert_int64(descr: &ColumnDescPtr, value: i64) -> Self {
712 match descr.converted_type() {
713 ConvertedType::INT_64 | ConvertedType::NONE => Field::Long(value),
714 ConvertedType::UINT_64 => Field::ULong(value as u64),
715 ConvertedType::TIME_MICROS => Field::TimeMicros(value),
716 ConvertedType::TIMESTAMP_MILLIS => Field::TimestampMillis(value),
717 ConvertedType::TIMESTAMP_MICROS => Field::TimestampMicros(value),
718 ConvertedType::DECIMAL => Field::Decimal(Decimal::from_i64(
719 value,
720 descr.type_precision(),
721 descr.type_scale(),
722 )),
723 _ => nyi!(descr, value),
724 }
725 }
726
727 #[inline]
730 pub fn convert_int96(_descr: &ColumnDescPtr, value: Int96) -> Self {
731 Field::TimestampMillis(value.to_millis())
732 }
733
734 #[inline]
736 pub fn convert_float(_descr: &ColumnDescPtr, value: f32) -> Self {
737 Field::Float(value)
738 }
739
740 #[inline]
742 pub fn convert_double(_descr: &ColumnDescPtr, value: f64) -> Self {
743 Field::Double(value)
744 }
745
746 #[inline]
749 pub fn convert_byte_array(descr: &ColumnDescPtr, value: ByteArray) -> Result<Self> {
750 let field = match descr.physical_type() {
751 PhysicalType::BYTE_ARRAY => match descr.converted_type() {
752 ConvertedType::UTF8 | ConvertedType::ENUM | ConvertedType::JSON => {
753 let value = String::from_utf8(value.data().to_vec()).map_err(|e| {
754 general_err!(
755 "Error reading BYTE_ARRAY as String. Bytes: {:?} Error: {:?}",
756 value.data(),
757 e
758 )
759 })?;
760 Field::Str(value)
761 }
762 ConvertedType::BSON | ConvertedType::NONE => Field::Bytes(value),
763 ConvertedType::DECIMAL => Field::Decimal(Decimal::from_bytes(
764 value,
765 descr.type_precision(),
766 descr.type_scale(),
767 )),
768 _ => nyi!(descr, value),
769 },
770 PhysicalType::FIXED_LEN_BYTE_ARRAY => match descr.converted_type() {
771 ConvertedType::DECIMAL => Field::Decimal(Decimal::from_bytes(
772 value,
773 descr.type_precision(),
774 descr.type_scale(),
775 )),
776 ConvertedType::NONE if descr.logical_type_ref() == Some(&LogicalType::Float16) => {
777 if value.len() != 2 {
778 return Err(general_err!(
779 "Error reading FIXED_LEN_BYTE_ARRAY as FLOAT16. Length must be 2, got {}",
780 value.len()
781 ));
782 }
783 let bytes = [value.data()[0], value.data()[1]];
784 Field::Float16(f16::from_le_bytes(bytes))
785 }
786 ConvertedType::NONE => Field::Bytes(value),
787 _ => nyi!(descr, value),
788 },
789 _ => nyi!(descr, value),
790 };
791 Ok(field)
792 }
793
794 #[cfg(any(feature = "json", test))]
796 pub fn to_json_value(&self) -> Value {
797 use base64::Engine;
798 use base64::prelude::BASE64_STANDARD;
799
800 match &self {
801 Field::Null => Value::Null,
802 Field::Bool(b) => Value::Bool(*b),
803 Field::Byte(n) => Value::Number(serde_json::Number::from(*n)),
804 Field::Short(n) => Value::Number(serde_json::Number::from(*n)),
805 Field::Int(n) => Value::Number(serde_json::Number::from(*n)),
806 Field::Long(n) => Value::Number(serde_json::Number::from(*n)),
807 Field::UByte(n) => Value::Number(serde_json::Number::from(*n)),
808 Field::UShort(n) => Value::Number(serde_json::Number::from(*n)),
809 Field::UInt(n) => Value::Number(serde_json::Number::from(*n)),
810 Field::ULong(n) => Value::Number(serde_json::Number::from(*n)),
811 Field::Float16(n) => serde_json::Number::from_f64(f64::from(*n))
812 .map(Value::Number)
813 .unwrap_or(Value::Null),
814 Field::Float(n) => serde_json::Number::from_f64(f64::from(*n))
815 .map(Value::Number)
816 .unwrap_or(Value::Null),
817 Field::Double(n) => serde_json::Number::from_f64(*n)
818 .map(Value::Number)
819 .unwrap_or(Value::Null),
820 Field::Decimal(n) => Value::String(convert_decimal_to_string(n)),
821 Field::Str(s) => Value::String(s.to_owned()),
822 Field::Bytes(b) => Value::String(BASE64_STANDARD.encode(b.data())),
823 Field::Date(d) => Value::String(convert_date_to_string(*d)),
824 Field::TimeMillis(t) => Value::String(convert_time_millis_to_string(*t)),
825 Field::TimeMicros(t) => Value::String(convert_time_micros_to_string(*t)),
826 Field::TimestampMillis(ts) => Value::String(convert_timestamp_millis_to_string(*ts)),
827 Field::TimestampMicros(ts) => Value::String(convert_timestamp_micros_to_string(*ts)),
828 Field::Group(row) => row.to_json_value(),
829 Field::ListInternal(fields) => {
830 Value::Array(fields.elements.iter().map(|f| f.to_json_value()).collect())
831 }
832 Field::MapInternal(map) => Value::Object(
833 map.entries
834 .iter()
835 .map(|(key_field, value_field)| {
836 let key_val = key_field.to_json_value();
837 let key_str = key_val
838 .as_str()
839 .map(|s| s.to_owned())
840 .unwrap_or_else(|| key_val.to_string());
841 (key_str, value_field.to_json_value())
842 })
843 .collect(),
844 ),
845 }
846 }
847}
848
849impl fmt::Display for Field {
850 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
851 match *self {
852 Field::Null => write!(f, "null"),
853 Field::Bool(value) => write!(f, "{value}"),
854 Field::Byte(value) => write!(f, "{value}"),
855 Field::Short(value) => write!(f, "{value}"),
856 Field::Int(value) => write!(f, "{value}"),
857 Field::Long(value) => write!(f, "{value}"),
858 Field::UByte(value) => write!(f, "{value}"),
859 Field::UShort(value) => write!(f, "{value}"),
860 Field::UInt(value) => write!(f, "{value}"),
861 Field::ULong(value) => write!(f, "{value}"),
862 Field::Float16(value) => {
863 if !value.is_finite() {
864 write!(f, "{value}")
865 } else if value.trunc() == value {
866 write!(f, "{value}.0")
867 } else {
868 write!(f, "{value}")
869 }
870 }
871 Field::Float(value) => {
872 if !(1e-15..=1e19).contains(&value) {
873 write!(f, "{value:E}")
874 } else if value.trunc() == value {
875 write!(f, "{value}.0")
876 } else {
877 write!(f, "{value}")
878 }
879 }
880 Field::Double(value) => {
881 if !(1e-15..=1e19).contains(&value) {
882 write!(f, "{value:E}")
883 } else if value.trunc() == value {
884 write!(f, "{value}.0")
885 } else {
886 write!(f, "{value}")
887 }
888 }
889 Field::Decimal(ref value) => {
890 write!(f, "{}", convert_decimal_to_string(value))
891 }
892 Field::Str(ref value) => write!(f, "\"{value}\""),
893 Field::Bytes(ref value) => write!(f, "{:?}", value.data()),
894 Field::Date(value) => write!(f, "{}", convert_date_to_string(value)),
895 Field::TimeMillis(value) => {
896 write!(f, "{}", convert_time_millis_to_string(value))
897 }
898 Field::TimeMicros(value) => {
899 write!(f, "{}", convert_time_micros_to_string(value))
900 }
901 Field::TimestampMillis(value) => {
902 write!(f, "{}", convert_timestamp_millis_to_string(value))
903 }
904 Field::TimestampMicros(value) => {
905 write!(f, "{}", convert_timestamp_micros_to_string(value))
906 }
907 Field::Group(ref fields) => write!(f, "{fields}"),
908 Field::ListInternal(ref list) => {
909 let elems = &list.elements;
910 write!(f, "[")?;
911 for (i, field) in elems.iter().enumerate() {
912 field.fmt(f)?;
913 if i < elems.len() - 1 {
914 write!(f, ", ")?;
915 }
916 }
917 write!(f, "]")
918 }
919 Field::MapInternal(ref map) => {
920 let entries = &map.entries;
921 write!(f, "{{")?;
922 for (i, (key, value)) in entries.iter().enumerate() {
923 key.fmt(f)?;
924 write!(f, " -> ")?;
925 value.fmt(f)?;
926 if i < entries.len() - 1 {
927 write!(f, ", ")?;
928 }
929 }
930 write!(f, "}}")
931 }
932 }
933 }
934}
935
936#[inline]
940fn convert_date_to_string(value: i32) -> String {
941 static NUM_SECONDS_IN_DAY: i64 = 60 * 60 * 24;
942 let dt = Utc
943 .timestamp_opt(value as i64 * NUM_SECONDS_IN_DAY, 0)
944 .unwrap();
945 format!("{}", dt.format("%Y-%m-%d"))
946}
947
948#[inline]
952fn convert_timestamp_millis_to_string(value: i64) -> String {
953 let dt = Utc.timestamp_millis_opt(value).unwrap();
954 format!("{}", dt.format("%Y-%m-%d %H:%M:%S%.3f %:z"))
955}
956
957#[inline]
961fn convert_timestamp_micros_to_string(value: i64) -> String {
962 let dt = Utc.timestamp_micros(value).unwrap();
963 format!("{}", dt.format("%Y-%m-%d %H:%M:%S%.6f %:z"))
964}
965
966#[inline]
970fn convert_time_millis_to_string(value: i32) -> String {
971 let total_ms = value as u64;
972 let hours = total_ms / (60 * 60 * 1000);
973 let minutes = (total_ms % (60 * 60 * 1000)) / (60 * 1000);
974 let seconds = (total_ms % (60 * 1000)) / 1000;
975 let millis = total_ms % 1000;
976 format!("{hours:02}:{minutes:02}:{seconds:02}.{millis:03}")
977}
978
979#[inline]
983fn convert_time_micros_to_string(value: i64) -> String {
984 let total_us = value as u64;
985 let hours = total_us / (60 * 60 * 1000 * 1000);
986 let minutes = (total_us % (60 * 60 * 1000 * 1000)) / (60 * 1000 * 1000);
987 let seconds = (total_us % (60 * 1000 * 1000)) / (1000 * 1000);
988 let micros = total_us % (1000 * 1000);
989 format!("{hours:02}:{minutes:02}:{seconds:02}.{micros:06}")
990}
991
992#[inline]
996fn convert_decimal_to_string(decimal: &Decimal) -> String {
997 assert!(decimal.scale() >= 0 && decimal.precision() >= decimal.scale());
998
999 let num = BigInt::from_signed_bytes_be(decimal.data());
1001
1002 let negative = i32::from(num.sign() == Sign::Minus);
1004 let mut num_str = num.to_string();
1005 let mut point = num_str.len() as i32 - decimal.scale() - negative;
1006
1007 if point <= 0 {
1009 while point < 0 {
1011 num_str.insert(negative as usize, '0');
1012 point += 1;
1013 }
1014 num_str.insert_str(negative as usize, "0.");
1015 } else {
1016 num_str.insert((point + negative) as usize, '.');
1019 }
1020
1021 num_str
1022}
1023
1024#[cfg(test)]
1025#[expect(clippy::many_single_char_names)]
1026mod tests {
1027 use super::*;
1028
1029 use std::f64::consts::PI;
1030 use std::sync::Arc;
1031
1032 use crate::schema::types::{ColumnDescriptor, ColumnPath, PrimitiveTypeBuilder};
1033
1034 macro_rules! make_column_descr {
1036 ($physical_type:expr, $logical_type:expr) => {{
1037 let tpe = PrimitiveTypeBuilder::new("col", $physical_type)
1038 .with_converted_type($logical_type)
1039 .build()
1040 .unwrap();
1041 Arc::new(ColumnDescriptor::new(
1042 Arc::new(tpe),
1043 0,
1044 0,
1045 ColumnPath::from("col"),
1046 ))
1047 }};
1048 ($physical_type:expr, $logical_type:expr, $len:expr, $prec:expr, $scale:expr) => {{
1049 let tpe = PrimitiveTypeBuilder::new("col", $physical_type)
1050 .with_converted_type($logical_type)
1051 .with_length($len)
1052 .with_precision($prec)
1053 .with_scale($scale)
1054 .build()
1055 .unwrap();
1056 Arc::new(ColumnDescriptor::new(
1057 Arc::new(tpe),
1058 0,
1059 0,
1060 ColumnPath::from("col"),
1061 ))
1062 }};
1063 }
1064
1065 #[test]
1066 fn test_row_convert_bool() {
1067 let descr = make_column_descr![PhysicalType::BOOLEAN, ConvertedType::NONE];
1069
1070 let row = Field::convert_bool(&descr, true);
1071 assert_eq!(row, Field::Bool(true));
1072
1073 let row = Field::convert_bool(&descr, false);
1074 assert_eq!(row, Field::Bool(false));
1075 }
1076
1077 #[test]
1078 fn test_row_convert_int32() {
1079 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::INT_8];
1080 let row = Field::convert_int32(&descr, 111);
1081 assert_eq!(row, Field::Byte(111));
1082
1083 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::INT_16];
1084 let row = Field::convert_int32(&descr, 222);
1085 assert_eq!(row, Field::Short(222));
1086
1087 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::INT_32];
1088 let row = Field::convert_int32(&descr, 333);
1089 assert_eq!(row, Field::Int(333));
1090
1091 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::UINT_8];
1092 let row = Field::convert_int32(&descr, -1);
1093 assert_eq!(row, Field::UByte(255));
1094
1095 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::UINT_16];
1096 let row = Field::convert_int32(&descr, 256);
1097 assert_eq!(row, Field::UShort(256));
1098
1099 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::UINT_32];
1100 let row = Field::convert_int32(&descr, 1234);
1101 assert_eq!(row, Field::UInt(1234));
1102
1103 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::NONE];
1104 let row = Field::convert_int32(&descr, 444);
1105 assert_eq!(row, Field::Int(444));
1106
1107 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::DATE];
1108 let row = Field::convert_int32(&descr, 14611);
1109 assert_eq!(row, Field::Date(14611));
1110
1111 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::TIME_MILLIS];
1112 let row = Field::convert_int32(&descr, 14611);
1113 assert_eq!(row, Field::TimeMillis(14611));
1114
1115 let descr = make_column_descr![PhysicalType::INT32, ConvertedType::DECIMAL, 0, 8, 2];
1116 let row = Field::convert_int32(&descr, 444);
1117 assert_eq!(row, Field::Decimal(Decimal::from_i32(444, 8, 2)));
1118 }
1119
1120 #[test]
1121 fn test_row_convert_int64() {
1122 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::INT_64];
1123 let row = Field::convert_int64(&descr, 1111);
1124 assert_eq!(row, Field::Long(1111));
1125
1126 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::UINT_64];
1127 let row = Field::convert_int64(&descr, 78239823);
1128 assert_eq!(row, Field::ULong(78239823));
1129
1130 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::TIMESTAMP_MILLIS];
1131 let row = Field::convert_int64(&descr, 1541186529153);
1132 assert_eq!(row, Field::TimestampMillis(1541186529153));
1133
1134 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::TIMESTAMP_MICROS];
1135 let row = Field::convert_int64(&descr, 1541186529153123);
1136 assert_eq!(row, Field::TimestampMicros(1541186529153123));
1137
1138 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::TIME_MICROS];
1139 let row = Field::convert_int64(&descr, 47445123456);
1140 assert_eq!(row, Field::TimeMicros(47445123456));
1141
1142 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::NONE];
1143 let row = Field::convert_int64(&descr, 2222);
1144 assert_eq!(row, Field::Long(2222));
1145
1146 let descr = make_column_descr![PhysicalType::INT64, ConvertedType::DECIMAL, 0, 8, 2];
1147 let row = Field::convert_int64(&descr, 3333);
1148 assert_eq!(row, Field::Decimal(Decimal::from_i64(3333, 8, 2)));
1149 }
1150
1151 #[test]
1152 fn test_row_convert_int96() {
1153 let descr = make_column_descr![PhysicalType::INT96, ConvertedType::NONE];
1155
1156 let value = Int96::from(vec![0, 0, 2454923]);
1157 let row = Field::convert_int96(&descr, value);
1158 assert_eq!(row, Field::TimestampMillis(1238544000000));
1159
1160 let value = Int96::from(vec![4165425152, 13, 2454923]);
1161 let row = Field::convert_int96(&descr, value);
1162 assert_eq!(row, Field::TimestampMillis(1238544060000));
1163 }
1164
1165 #[test]
1166 fn test_row_convert_float() {
1167 let descr = make_column_descr![PhysicalType::FLOAT, ConvertedType::NONE];
1169 let row = Field::convert_float(&descr, 2.31);
1170 assert_eq!(row, Field::Float(2.31));
1171 }
1172
1173 #[test]
1174 fn test_row_convert_double() {
1175 let descr = make_column_descr![PhysicalType::DOUBLE, ConvertedType::NONE];
1177 let row = Field::convert_double(&descr, 1.56);
1178 assert_eq!(row, Field::Double(1.56));
1179 }
1180
1181 #[test]
1182 fn test_row_convert_byte_array() {
1183 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::UTF8];
1185 let value = ByteArray::from(vec![b'A', b'B', b'C', b'D']);
1186 let row = Field::convert_byte_array(&descr, value);
1187 assert_eq!(row.unwrap(), Field::Str("ABCD".to_string()));
1188
1189 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::ENUM];
1191 let value = ByteArray::from(vec![b'1', b'2', b'3']);
1192 let row = Field::convert_byte_array(&descr, value);
1193 assert_eq!(row.unwrap(), Field::Str("123".to_string()));
1194
1195 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::JSON];
1197 let value = ByteArray::from(vec![b'{', b'"', b'a', b'"', b':', b'1', b'}']);
1198 let row = Field::convert_byte_array(&descr, value);
1199 assert_eq!(row.unwrap(), Field::Str("{\"a\":1}".to_string()));
1200
1201 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::NONE];
1203 let value = ByteArray::from(vec![1, 2, 3, 4, 5]);
1204 let row = Field::convert_byte_array(&descr, value.clone());
1205 assert_eq!(row.unwrap(), Field::Bytes(value));
1206
1207 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::BSON];
1209 let value = ByteArray::from(vec![1, 2, 3, 4, 5]);
1210 let row = Field::convert_byte_array(&descr, value.clone());
1211 assert_eq!(row.unwrap(), Field::Bytes(value));
1212
1213 let descr = make_column_descr![PhysicalType::BYTE_ARRAY, ConvertedType::DECIMAL, 0, 8, 2];
1215 let value = ByteArray::from(vec![207, 200]);
1216 let row = Field::convert_byte_array(&descr, value.clone());
1217 assert_eq!(
1218 row.unwrap(),
1219 Field::Decimal(Decimal::from_bytes(value, 8, 2))
1220 );
1221
1222 let descr = make_column_descr![
1224 PhysicalType::FIXED_LEN_BYTE_ARRAY,
1225 ConvertedType::DECIMAL,
1226 8,
1227 17,
1228 5
1229 ];
1230 let value = ByteArray::from(vec![0, 0, 0, 0, 0, 4, 147, 224]);
1231 let row = Field::convert_byte_array(&descr, value.clone());
1232 assert_eq!(
1233 row.unwrap(),
1234 Field::Decimal(Decimal::from_bytes(value, 17, 5))
1235 );
1236
1237 let descr = {
1239 let tpe = PrimitiveTypeBuilder::new("col", PhysicalType::FIXED_LEN_BYTE_ARRAY)
1240 .with_logical_type(Some(LogicalType::Float16))
1241 .with_length(2)
1242 .build()
1243 .unwrap();
1244 Arc::new(ColumnDescriptor::new(
1245 Arc::new(tpe),
1246 0,
1247 0,
1248 ColumnPath::from("col"),
1249 ))
1250 };
1251 let value = ByteArray::from(f16::PI);
1252 let row = Field::convert_byte_array(&descr, value.clone());
1253 assert_eq!(row.unwrap(), Field::Float16(f16::PI));
1254
1255 let descr = make_column_descr![
1257 PhysicalType::FIXED_LEN_BYTE_ARRAY,
1258 ConvertedType::NONE,
1259 6,
1260 0,
1261 0
1262 ];
1263 let value = ByteArray::from(vec![1, 2, 3, 4, 5, 6]);
1264 let row = Field::convert_byte_array(&descr, value.clone());
1265 assert_eq!(row.unwrap(), Field::Bytes(value));
1266 }
1267
1268 #[test]
1269 fn test_convert_date_to_string() {
1270 fn check_date_conversion(y: u32, m: u32, d: u32) {
1271 let datetime = chrono::NaiveDate::from_ymd_opt(y as i32, m, d)
1272 .unwrap()
1273 .and_hms_opt(0, 0, 0)
1274 .unwrap();
1275 let dt = Utc.from_utc_datetime(&datetime);
1276 let res = convert_date_to_string((dt.timestamp() / 60 / 60 / 24) as i32);
1277 let exp = format!("{}", dt.format("%Y-%m-%d"));
1278 assert_eq!(res, exp);
1279 }
1280
1281 check_date_conversion(1969, 12, 31);
1282 check_date_conversion(2010, 1, 2);
1283 check_date_conversion(2014, 5, 1);
1284 check_date_conversion(2016, 2, 29);
1285 check_date_conversion(2017, 9, 12);
1286 check_date_conversion(2018, 3, 31);
1287 }
1288
1289 #[test]
1290 fn test_convert_timestamp_millis_to_string() {
1291 fn check_datetime_conversion(
1292 (y, m, d, h, mi, s, milli): (u32, u32, u32, u32, u32, u32, u32),
1293 exp: &str,
1294 ) {
1295 let datetime = chrono::NaiveDate::from_ymd_opt(y as i32, m, d)
1296 .unwrap()
1297 .and_hms_milli_opt(h, mi, s, milli)
1298 .unwrap();
1299 let dt = Utc.from_utc_datetime(&datetime);
1300 let res = convert_timestamp_millis_to_string(dt.timestamp_millis());
1301 assert_eq!(res, exp);
1302 }
1303
1304 check_datetime_conversion((1969, 9, 10, 1, 2, 3, 4), "1969-09-10 01:02:03.004 +00:00");
1305 check_datetime_conversion(
1306 (2010, 1, 2, 13, 12, 54, 42),
1307 "2010-01-02 13:12:54.042 +00:00",
1308 );
1309 check_datetime_conversion((2011, 1, 3, 8, 23, 1, 27), "2011-01-03 08:23:01.027 +00:00");
1310 check_datetime_conversion((2012, 4, 5, 11, 6, 32, 0), "2012-04-05 11:06:32.000 +00:00");
1311 check_datetime_conversion(
1312 (2013, 5, 12, 16, 38, 0, 15),
1313 "2013-05-12 16:38:00.015 +00:00",
1314 );
1315 check_datetime_conversion(
1316 (2014, 11, 28, 21, 15, 12, 59),
1317 "2014-11-28 21:15:12.059 +00:00",
1318 );
1319 }
1320
1321 #[test]
1322 fn test_convert_timestamp_micros_to_string() {
1323 fn check_datetime_conversion(
1324 (y, m, d, h, mi, s, micro): (u32, u32, u32, u32, u32, u32, u32),
1325 exp: &str,
1326 ) {
1327 let datetime = chrono::NaiveDate::from_ymd_opt(y as i32, m, d)
1328 .unwrap()
1329 .and_hms_micro_opt(h, mi, s, micro)
1330 .unwrap();
1331 let dt = Utc.from_utc_datetime(&datetime);
1332 let res = convert_timestamp_micros_to_string(dt.timestamp_micros());
1333 assert_eq!(res, exp);
1334 }
1335
1336 check_datetime_conversion(
1337 (1969, 9, 10, 1, 2, 3, 4),
1338 "1969-09-10 01:02:03.000004 +00:00",
1339 );
1340 check_datetime_conversion(
1341 (2010, 1, 2, 13, 12, 54, 42),
1342 "2010-01-02 13:12:54.000042 +00:00",
1343 );
1344 check_datetime_conversion(
1345 (2011, 1, 3, 8, 23, 1, 27),
1346 "2011-01-03 08:23:01.000027 +00:00",
1347 );
1348 check_datetime_conversion(
1349 (2012, 4, 5, 11, 6, 32, 0),
1350 "2012-04-05 11:06:32.000000 +00:00",
1351 );
1352 check_datetime_conversion(
1353 (2013, 5, 12, 16, 38, 0, 15),
1354 "2013-05-12 16:38:00.000015 +00:00",
1355 );
1356 check_datetime_conversion(
1357 (2014, 11, 28, 21, 15, 12, 59),
1358 "2014-11-28 21:15:12.000059 +00:00",
1359 );
1360 }
1361
1362 #[test]
1363 #[cfg_attr(miri, ignore)] fn test_convert_float16_to_string() {
1365 assert_eq!(format!("{}", Field::Float16(f16::ONE)), "1.0");
1366 assert_eq!(format!("{}", Field::Float16(f16::PI)), "3.140625");
1367 assert_eq!(format!("{}", Field::Float16(f16::MAX)), "65504.0");
1368 assert_eq!(format!("{}", Field::Float16(f16::NAN)), "NaN");
1369 assert_eq!(format!("{}", Field::Float16(f16::INFINITY)), "inf");
1370 assert_eq!(format!("{}", Field::Float16(f16::NEG_INFINITY)), "-inf");
1371 assert_eq!(format!("{}", Field::Float16(f16::ZERO)), "0.0");
1372 assert_eq!(format!("{}", Field::Float16(f16::NEG_ZERO)), "-0.0");
1373 }
1374
1375 #[test]
1376 fn test_convert_float_to_string() {
1377 assert_eq!(format!("{}", Field::Float(1.0)), "1.0");
1378 assert_eq!(format!("{}", Field::Float(9.63)), "9.63");
1379 assert_eq!(format!("{}", Field::Float(1e-15)), "0.000000000000001");
1380 assert_eq!(format!("{}", Field::Float(1e-16)), "1E-16");
1381 assert_eq!(format!("{}", Field::Float(1e19)), "10000000000000000000.0");
1382 assert_eq!(format!("{}", Field::Float(1e20)), "1E20");
1383 assert_eq!(format!("{}", Field::Float(1.7976931E30)), "1.7976931E30");
1384 assert_eq!(format!("{}", Field::Float(-1.7976931E30)), "-1.7976931E30");
1385 }
1386
1387 #[test]
1388 fn test_convert_double_to_string() {
1389 assert_eq!(format!("{}", Field::Double(1.0)), "1.0");
1390 assert_eq!(format!("{}", Field::Double(9.63)), "9.63");
1391 assert_eq!(format!("{}", Field::Double(1e-15)), "0.000000000000001");
1392 assert_eq!(format!("{}", Field::Double(1e-16)), "1E-16");
1393 assert_eq!(format!("{}", Field::Double(1e19)), "10000000000000000000.0");
1394 assert_eq!(format!("{}", Field::Double(1e20)), "1E20");
1395 assert_eq!(
1396 format!("{}", Field::Double(1.79769313486E308)),
1397 "1.79769313486E308"
1398 );
1399 assert_eq!(
1400 format!("{}", Field::Double(-1.79769313486E308)),
1401 "-1.79769313486E308"
1402 );
1403 }
1404
1405 #[test]
1406 fn test_convert_decimal_to_string() {
1407 fn check_decimal(bytes: Vec<u8>, precision: i32, scale: i32, res: &str) {
1409 let decimal = Decimal::from_bytes(ByteArray::from(bytes), precision, scale);
1410 assert_eq!(convert_decimal_to_string(&decimal), res);
1411 }
1412
1413 check_decimal(
1415 vec![0, 0, 0, 0, 0, 0, 0, 0, 13, 224, 182, 179, 167, 100, 0, 0],
1416 38,
1417 18,
1418 "1.000000000000000000",
1419 );
1420 check_decimal(
1421 vec![
1422 249, 233, 247, 16, 185, 192, 202, 223, 215, 165, 192, 166, 67, 72,
1423 ],
1424 36,
1425 28,
1426 "-12344.0242342304923409234234293432",
1427 );
1428 check_decimal(vec![0, 0, 0, 0, 0, 4, 147, 224], 17, 5, "3.00000");
1429 check_decimal(vec![0, 0, 0, 0, 1, 201, 195, 140], 18, 2, "300000.12");
1430 check_decimal(vec![207, 200], 10, 2, "-123.44");
1431 check_decimal(vec![207, 200], 10, 8, "-0.00012344");
1432 check_decimal(vec![48, 57], 5, 5, "0.12345");
1433 check_decimal(vec![207, 199], 5, 5, "-0.12345");
1434 check_decimal(vec![45], 5, 5, "0.00045");
1435 }
1436
1437 #[test]
1438 #[cfg_attr(miri, ignore)] fn test_row_display() {
1440 assert_eq!(format!("{}", Field::Null), "null");
1442 assert_eq!(format!("{}", Field::Bool(true)), "true");
1443 assert_eq!(format!("{}", Field::Bool(false)), "false");
1444 assert_eq!(format!("{}", Field::Byte(1)), "1");
1445 assert_eq!(format!("{}", Field::Short(2)), "2");
1446 assert_eq!(format!("{}", Field::Int(3)), "3");
1447 assert_eq!(format!("{}", Field::Long(4)), "4");
1448 assert_eq!(format!("{}", Field::UByte(1)), "1");
1449 assert_eq!(format!("{}", Field::UShort(2)), "2");
1450 assert_eq!(format!("{}", Field::UInt(3)), "3");
1451 assert_eq!(format!("{}", Field::ULong(4)), "4");
1452 assert_eq!(format!("{}", Field::Float16(f16::E)), "2.71875");
1453 assert_eq!(format!("{}", Field::Float(5.0)), "5.0");
1454 assert_eq!(format!("{}", Field::Float(5.1234)), "5.1234");
1455 assert_eq!(format!("{}", Field::Double(6.0)), "6.0");
1456 assert_eq!(format!("{}", Field::Double(6.1234)), "6.1234");
1457 assert_eq!(format!("{}", Field::Str("abc".to_string())), "\"abc\"");
1458 assert_eq!(
1459 format!("{}", Field::Bytes(ByteArray::from(vec![1, 2, 3]))),
1460 "[1, 2, 3]"
1461 );
1462 assert_eq!(
1463 format!("{}", Field::Date(14611)),
1464 convert_date_to_string(14611)
1465 );
1466 assert_eq!(
1467 format!("{}", Field::TimestampMillis(1262391174000)),
1468 convert_timestamp_millis_to_string(1262391174000)
1469 );
1470 assert_eq!(
1471 format!("{}", Field::TimestampMicros(1262391174000000)),
1472 convert_timestamp_micros_to_string(1262391174000000)
1473 );
1474 assert_eq!(
1475 format!("{}", Field::Decimal(Decimal::from_i32(4, 8, 2))),
1476 convert_decimal_to_string(&Decimal::from_i32(4, 8, 2))
1477 );
1478
1479 let fields = vec![
1481 ("x".to_string(), Field::Null),
1482 ("Y".to_string(), Field::Int(2)),
1483 ("z".to_string(), Field::Float(3.1)),
1484 ("a".to_string(), Field::Str("abc".to_string())),
1485 ];
1486 let row = Field::Group(Row::new(fields));
1487 assert_eq!(format!("{row}"), "{x: null, Y: 2, z: 3.1, a: \"abc\"}");
1488
1489 let row = Field::ListInternal(make_list(vec![
1490 Field::Int(2),
1491 Field::Int(1),
1492 Field::Null,
1493 Field::Int(12),
1494 ]));
1495 assert_eq!(format!("{row}"), "[2, 1, null, 12]");
1496
1497 let row = Field::MapInternal(make_map(vec![
1498 (Field::Int(1), Field::Float(1.2)),
1499 (Field::Int(2), Field::Float(4.5)),
1500 (Field::Int(3), Field::Float(2.3)),
1501 ]));
1502 assert_eq!(format!("{row}"), "{1 -> 1.2, 2 -> 4.5, 3 -> 2.3}");
1503 }
1504
1505 #[test]
1506 fn test_is_primitive() {
1507 assert!(Field::Null.is_primitive());
1509 assert!(Field::Bool(true).is_primitive());
1510 assert!(Field::Bool(false).is_primitive());
1511 assert!(Field::Byte(1).is_primitive());
1512 assert!(Field::Short(2).is_primitive());
1513 assert!(Field::Int(3).is_primitive());
1514 assert!(Field::Long(4).is_primitive());
1515 assert!(Field::UByte(1).is_primitive());
1516 assert!(Field::UShort(2).is_primitive());
1517 assert!(Field::UInt(3).is_primitive());
1518 assert!(Field::ULong(4).is_primitive());
1519 assert!(Field::Float16(f16::E).is_primitive());
1520 assert!(Field::Float(5.0).is_primitive());
1521 assert!(Field::Float(5.1234).is_primitive());
1522 assert!(Field::Double(6.0).is_primitive());
1523 assert!(Field::Double(6.1234).is_primitive());
1524 assert!(Field::Str("abc".to_string()).is_primitive());
1525 assert!(Field::Bytes(ByteArray::from(vec![1, 2, 3])).is_primitive());
1526 assert!(Field::TimestampMillis(12345678).is_primitive());
1527 assert!(Field::TimestampMicros(12345678901).is_primitive());
1528 assert!(Field::Decimal(Decimal::from_i32(4, 8, 2)).is_primitive());
1529
1530 assert!(
1532 !Field::Group(Row::new(vec![
1533 ("x".to_string(), Field::Null),
1534 ("Y".to_string(), Field::Int(2)),
1535 ("z".to_string(), Field::Float(3.1)),
1536 ("a".to_string(), Field::Str("abc".to_string()))
1537 ]))
1538 .is_primitive()
1539 );
1540
1541 assert!(
1542 !Field::ListInternal(make_list(vec![
1543 Field::Int(2),
1544 Field::Int(1),
1545 Field::Null,
1546 Field::Int(12)
1547 ]))
1548 .is_primitive()
1549 );
1550
1551 assert!(
1552 !Field::MapInternal(make_map(vec![
1553 (Field::Int(1), Field::Float(1.2)),
1554 (Field::Int(2), Field::Float(4.5)),
1555 (Field::Int(3), Field::Float(2.3))
1556 ]))
1557 .is_primitive()
1558 );
1559 }
1560
1561 #[test]
1562 #[cfg_attr(miri, ignore)] fn test_row_primitive_field_fmt() {
1564 let row = Row::new(vec![
1566 ("00".to_string(), Field::Null),
1567 ("01".to_string(), Field::Bool(false)),
1568 ("02".to_string(), Field::Byte(3)),
1569 ("03".to_string(), Field::Short(4)),
1570 ("04".to_string(), Field::Int(5)),
1571 ("05".to_string(), Field::Long(6)),
1572 ("06".to_string(), Field::UByte(7)),
1573 ("07".to_string(), Field::UShort(8)),
1574 ("08".to_string(), Field::UInt(9)),
1575 ("09".to_string(), Field::ULong(10)),
1576 ("10".to_string(), Field::Float(11.1)),
1577 ("11".to_string(), Field::Double(12.1)),
1578 ("12".to_string(), Field::Str("abc".to_string())),
1579 (
1580 "13".to_string(),
1581 Field::Bytes(ByteArray::from(vec![1, 2, 3, 4, 5])),
1582 ),
1583 ("14".to_string(), Field::Date(14611)),
1584 ("15".to_string(), Field::TimestampMillis(1262391174000)),
1585 ("16".to_string(), Field::TimestampMicros(1262391174000000)),
1586 ("17".to_string(), Field::Decimal(Decimal::from_i32(4, 7, 2))),
1587 ("18".to_string(), Field::Float16(f16::PI)),
1588 ]);
1589
1590 assert_eq!("null", format!("{}", row.fmt(0)));
1591 assert_eq!("false", format!("{}", row.fmt(1)));
1592 assert_eq!("3", format!("{}", row.fmt(2)));
1593 assert_eq!("4", format!("{}", row.fmt(3)));
1594 assert_eq!("5", format!("{}", row.fmt(4)));
1595 assert_eq!("6", format!("{}", row.fmt(5)));
1596 assert_eq!("7", format!("{}", row.fmt(6)));
1597 assert_eq!("8", format!("{}", row.fmt(7)));
1598 assert_eq!("9", format!("{}", row.fmt(8)));
1599 assert_eq!("10", format!("{}", row.fmt(9)));
1600 assert_eq!("11.1", format!("{}", row.fmt(10)));
1601 assert_eq!("12.1", format!("{}", row.fmt(11)));
1602 assert_eq!("\"abc\"", format!("{}", row.fmt(12)));
1603 assert_eq!("[1, 2, 3, 4, 5]", format!("{}", row.fmt(13)));
1604 assert_eq!(convert_date_to_string(14611), format!("{}", row.fmt(14)));
1605 assert_eq!(
1606 convert_timestamp_millis_to_string(1262391174000),
1607 format!("{}", row.fmt(15))
1608 );
1609 assert_eq!(
1610 convert_timestamp_micros_to_string(1262391174000000),
1611 format!("{}", row.fmt(16))
1612 );
1613 assert_eq!("0.04", format!("{}", row.fmt(17)));
1614 assert_eq!("3.140625", format!("{}", row.fmt(18)));
1615 }
1616
1617 #[test]
1618 fn test_row_complex_field_fmt() {
1619 let row = Row::new(vec![
1621 (
1622 "00".to_string(),
1623 Field::Group(Row::new(vec![
1624 ("x".to_string(), Field::Null),
1625 ("Y".to_string(), Field::Int(2)),
1626 ])),
1627 ),
1628 (
1629 "01".to_string(),
1630 Field::ListInternal(make_list(vec![
1631 Field::Int(2),
1632 Field::Int(1),
1633 Field::Null,
1634 Field::Int(12),
1635 ])),
1636 ),
1637 (
1638 "02".to_string(),
1639 Field::MapInternal(make_map(vec![
1640 (Field::Int(1), Field::Float(1.2)),
1641 (Field::Int(2), Field::Float(4.5)),
1642 (Field::Int(3), Field::Float(2.3)),
1643 ])),
1644 ),
1645 ]);
1646
1647 assert_eq!("{x: null, Y: 2}", format!("{}", row.fmt(0)));
1648 assert_eq!("[2, 1, null, 12]", format!("{}", row.fmt(1)));
1649 assert_eq!("{1 -> 1.2, 2 -> 4.5, 3 -> 2.3}", format!("{}", row.fmt(2)));
1650 }
1651
1652 #[test]
1653 #[cfg_attr(miri, ignore)] fn test_row_primitive_accessors() {
1655 let row = Row::new(vec![
1657 ("a".to_string(), Field::Null),
1658 ("b".to_string(), Field::Bool(false)),
1659 ("c".to_string(), Field::Byte(3)),
1660 ("d".to_string(), Field::Short(4)),
1661 ("e".to_string(), Field::Int(5)),
1662 ("f".to_string(), Field::Long(6)),
1663 ("g".to_string(), Field::UByte(3)),
1664 ("h".to_string(), Field::UShort(4)),
1665 ("i".to_string(), Field::UInt(5)),
1666 ("j".to_string(), Field::ULong(6)),
1667 ("k".to_string(), Field::Float(7.1)),
1668 ("l".to_string(), Field::Double(8.1)),
1669 ("m".to_string(), Field::Str("abc".to_string())),
1670 (
1671 "n".to_string(),
1672 Field::Bytes(ByteArray::from(vec![1, 2, 3, 4, 5])),
1673 ),
1674 ("o".to_string(), Field::Decimal(Decimal::from_i32(4, 7, 2))),
1675 ("p".to_string(), Field::Float16(f16::from_f32(9.1))),
1676 ]);
1677
1678 assert!(row.is_null(0).unwrap());
1679 assert!(!row.is_null(1).unwrap());
1680 assert!(!row.get_bool(1).unwrap());
1681 assert_eq!(3, row.get_byte(2).unwrap());
1682 assert_eq!(4, row.get_short(3).unwrap());
1683 assert_eq!(5, row.get_int(4).unwrap());
1684 assert_eq!(6, row.get_long(5).unwrap());
1685 assert_eq!(3, row.get_ubyte(6).unwrap());
1686 assert_eq!(4, row.get_ushort(7).unwrap());
1687 assert_eq!(5, row.get_uint(8).unwrap());
1688 assert_eq!(6, row.get_ulong(9).unwrap());
1689 assert!((7.1 - row.get_float(10).unwrap()).abs() < f32::EPSILON);
1690 assert!((8.1 - row.get_double(11).unwrap()).abs() < f64::EPSILON);
1691 assert_eq!("abc", row.get_string(12).unwrap());
1692 assert_eq!(5, row.get_bytes(13).unwrap().len());
1693 assert_eq!(7, row.get_decimal(14).unwrap().precision());
1694 assert!((f16::from_f32(9.1) - row.get_float16(15).unwrap()).abs() < f16::EPSILON);
1695
1696 assert!(matches!(
1697 row.is_null(16).unwrap_err(),
1698 ParquetError::IndexOutOfBound(16, 16),
1699 ));
1700 assert!(matches!(
1701 row.get_bool(16).unwrap_err(),
1702 ParquetError::IndexOutOfBound(16, 16),
1703 ));
1704 assert!(matches!(
1705 row.get_byte(16).unwrap_err(),
1706 ParquetError::IndexOutOfBound(16, 16),
1707 ));
1708 assert!(matches!(
1709 row.get_short(16).unwrap_err(),
1710 ParquetError::IndexOutOfBound(16, 16),
1711 ));
1712 assert!(matches!(
1713 row.get_int(16).unwrap_err(),
1714 ParquetError::IndexOutOfBound(16, 16),
1715 ));
1716 assert!(matches!(
1717 row.get_long(16).unwrap_err(),
1718 ParquetError::IndexOutOfBound(16, 16),
1719 ));
1720 assert!(matches!(
1721 row.get_ubyte(16).unwrap_err(),
1722 ParquetError::IndexOutOfBound(16, 16),
1723 ));
1724 assert!(matches!(
1725 row.get_ushort(16).unwrap_err(),
1726 ParquetError::IndexOutOfBound(16, 16),
1727 ));
1728 assert!(matches!(
1729 row.get_uint(16).unwrap_err(),
1730 ParquetError::IndexOutOfBound(16, 16),
1731 ));
1732 assert!(matches!(
1733 row.get_ulong(16).unwrap_err(),
1734 ParquetError::IndexOutOfBound(16, 16),
1735 ));
1736 assert!(matches!(
1737 row.get_float(16).unwrap_err(),
1738 ParquetError::IndexOutOfBound(16, 16),
1739 ));
1740 assert!(matches!(
1741 row.get_double(16).unwrap_err(),
1742 ParquetError::IndexOutOfBound(16, 16),
1743 ));
1744 assert!(matches!(
1745 row.get_string(16).unwrap_err(),
1746 ParquetError::IndexOutOfBound(16, 16),
1747 ));
1748 assert!(matches!(
1749 row.get_bytes(16).unwrap_err(),
1750 ParquetError::IndexOutOfBound(16, 16),
1751 ));
1752 assert!(matches!(
1753 row.get_decimal(16).unwrap_err(),
1754 ParquetError::IndexOutOfBound(16, 16),
1755 ));
1756 assert!(matches!(
1757 row.get_float16(16).unwrap_err(),
1758 ParquetError::IndexOutOfBound(16, 16),
1759 ));
1760 }
1761
1762 #[test]
1763 #[cfg_attr(miri, ignore)] fn test_row_primitive_invalid_accessors() {
1765 let row = Row::new(vec![
1767 ("a".to_string(), Field::Null),
1768 ("b".to_string(), Field::Bool(false)),
1769 ("c".to_string(), Field::Byte(3)),
1770 ("d".to_string(), Field::Short(4)),
1771 ("e".to_string(), Field::Int(5)),
1772 ("f".to_string(), Field::Long(6)),
1773 ("g".to_string(), Field::UByte(3)),
1774 ("h".to_string(), Field::UShort(4)),
1775 ("i".to_string(), Field::UInt(5)),
1776 ("j".to_string(), Field::ULong(6)),
1777 ("k".to_string(), Field::Float(7.1)),
1778 ("l".to_string(), Field::Double(8.1)),
1779 ("m".to_string(), Field::Str("abc".to_string())),
1780 (
1781 "n".to_string(),
1782 Field::Bytes(ByteArray::from(vec![1, 2, 3, 4, 5])),
1783 ),
1784 ("o".to_string(), Field::Decimal(Decimal::from_i32(4, 7, 2))),
1785 ("p".to_string(), Field::Float16(f16::from_f32(9.1))),
1786 ]);
1787
1788 for i in 0..row.len() {
1789 assert!(row.get_group(i).is_err());
1790 }
1791 }
1792
1793 #[test]
1794 fn test_row_complex_accessors() {
1795 let row = Row::new(vec![
1796 (
1797 "a".to_string(),
1798 Field::Group(Row::new(vec![
1799 ("x".to_string(), Field::Null),
1800 ("Y".to_string(), Field::Int(2)),
1801 ])),
1802 ),
1803 (
1804 "b".to_string(),
1805 Field::ListInternal(make_list(vec![
1806 Field::Int(2),
1807 Field::Int(1),
1808 Field::Null,
1809 Field::Int(12),
1810 ])),
1811 ),
1812 (
1813 "c".to_string(),
1814 Field::MapInternal(make_map(vec![
1815 (Field::Int(1), Field::Float(1.2)),
1816 (Field::Int(2), Field::Float(4.5)),
1817 (Field::Int(3), Field::Float(2.3)),
1818 ])),
1819 ),
1820 ]);
1821
1822 assert_eq!(2, row.get_group(0).unwrap().len());
1823 assert_eq!(4, row.get_list(1).unwrap().len());
1824 assert_eq!(3, row.get_map(2).unwrap().len());
1825 }
1826
1827 #[test]
1828 fn test_row_complex_invalid_accessors() {
1829 let row = Row::new(vec![
1830 (
1831 "a".to_string(),
1832 Field::Group(Row::new(vec![
1833 ("x".to_string(), Field::Null),
1834 ("Y".to_string(), Field::Int(2)),
1835 ])),
1836 ),
1837 (
1838 "b".to_string(),
1839 Field::ListInternal(make_list(vec![
1840 Field::Int(2),
1841 Field::Int(1),
1842 Field::Null,
1843 Field::Int(12),
1844 ])),
1845 ),
1846 (
1847 "c".to_string(),
1848 Field::MapInternal(make_map(vec![
1849 (Field::Int(1), Field::Float(1.2)),
1850 (Field::Int(2), Field::Float(4.5)),
1851 (Field::Int(3), Field::Float(2.3)),
1852 ])),
1853 ),
1854 ]);
1855
1856 assert_eq!(
1857 row.get_float(0).unwrap_err().to_string(),
1858 "Parquet error: Cannot access Group as Float"
1859 );
1860 assert_eq!(
1861 row.get_float(1).unwrap_err().to_string(),
1862 "Parquet error: Cannot access ListInternal as Float"
1863 );
1864 assert_eq!(
1865 row.get_float(2).unwrap_err().to_string(),
1866 "Parquet error: Cannot access MapInternal as Float",
1867 );
1868 }
1869
1870 #[test]
1871 #[cfg_attr(miri, ignore)] fn test_list_primitive_accessors() {
1873 let list = make_list(vec![Field::Bool(false)]);
1875 assert!(!list.get_bool(0).unwrap());
1876
1877 let list = make_list(vec![Field::Byte(3), Field::Byte(4)]);
1878 assert_eq!(4, list.get_byte(1).unwrap());
1879
1880 let list = make_list(vec![Field::Short(4), Field::Short(5), Field::Short(6)]);
1881 assert_eq!(6, list.get_short(2).unwrap());
1882
1883 let list = make_list(vec![Field::Int(5)]);
1884 assert_eq!(5, list.get_int(0).unwrap());
1885
1886 let list = make_list(vec![Field::Long(6), Field::Long(7)]);
1887 assert_eq!(7, list.get_long(1).unwrap());
1888
1889 let list = make_list(vec![Field::UByte(3), Field::UByte(4)]);
1890 assert_eq!(4, list.get_ubyte(1).unwrap());
1891
1892 let list = make_list(vec![Field::UShort(4), Field::UShort(5), Field::UShort(6)]);
1893 assert_eq!(6, list.get_ushort(2).unwrap());
1894
1895 let list = make_list(vec![Field::UInt(5)]);
1896 assert_eq!(5, list.get_uint(0).unwrap());
1897
1898 let list = make_list(vec![Field::ULong(6), Field::ULong(7)]);
1899 assert_eq!(7, list.get_ulong(1).unwrap());
1900
1901 let list = make_list(vec![Field::Float16(f16::PI)]);
1902 assert!((f16::PI - list.get_float16(0).unwrap()).abs() < f16::EPSILON);
1903
1904 let list = make_list(vec![
1905 Field::Float(8.1),
1906 Field::Float(9.2),
1907 Field::Float(10.3),
1908 ]);
1909 assert!((10.3 - list.get_float(2).unwrap()).abs() < f32::EPSILON);
1910
1911 let list = make_list(vec![Field::Double(PI)]);
1912 assert!((PI - list.get_double(0).unwrap()).abs() < f64::EPSILON);
1913
1914 let list = make_list(vec![Field::Str("abc".to_string())]);
1915 assert_eq!(&"abc".to_string(), list.get_string(0).unwrap());
1916
1917 let list = make_list(vec![Field::Bytes(ByteArray::from(vec![1, 2, 3, 4, 5]))]);
1918 assert_eq!(&[1, 2, 3, 4, 5], list.get_bytes(0).unwrap().data());
1919
1920 let list = make_list(vec![Field::Decimal(Decimal::from_i32(4, 5, 2))]);
1921 assert_eq!(&[0, 0, 0, 4], list.get_decimal(0).unwrap().data());
1922 }
1923
1924 #[test]
1925 fn test_list_primitive_invalid_accessors() {
1926 let list = make_list(vec![Field::Bool(false)]);
1928 assert!(list.get_byte(0).is_err());
1929
1930 let list = make_list(vec![Field::Byte(3), Field::Byte(4)]);
1931 assert!(list.get_short(1).is_err());
1932
1933 let list = make_list(vec![Field::Short(4), Field::Short(5), Field::Short(6)]);
1934 assert!(list.get_int(2).is_err());
1935
1936 let list = make_list(vec![Field::Int(5)]);
1937 assert!(list.get_long(0).is_err());
1938
1939 let list = make_list(vec![Field::Long(6), Field::Long(7)]);
1940 assert!(list.get_float(1).is_err());
1941
1942 let list = make_list(vec![Field::UByte(3), Field::UByte(4)]);
1943 assert!(list.get_short(1).is_err());
1944
1945 let list = make_list(vec![Field::UShort(4), Field::UShort(5), Field::UShort(6)]);
1946 assert!(list.get_int(2).is_err());
1947
1948 let list = make_list(vec![Field::UInt(5)]);
1949 assert!(list.get_long(0).is_err());
1950
1951 let list = make_list(vec![Field::ULong(6), Field::ULong(7)]);
1952 assert!(list.get_float(1).is_err());
1953
1954 let list = make_list(vec![Field::Float16(f16::PI)]);
1955 assert!(list.get_string(0).is_err());
1956
1957 let list = make_list(vec![
1958 Field::Float(8.1),
1959 Field::Float(9.2),
1960 Field::Float(10.3),
1961 ]);
1962 assert!(list.get_double(2).is_err());
1963
1964 let list = make_list(vec![Field::Double(PI)]);
1965 assert!(list.get_string(0).is_err());
1966
1967 let list = make_list(vec![Field::Str("abc".to_string())]);
1968 assert!(list.get_bytes(0).is_err());
1969
1970 let list = make_list(vec![Field::Bytes(ByteArray::from(vec![1, 2, 3, 4, 5]))]);
1971 assert!(list.get_bool(0).is_err());
1972
1973 let list = make_list(vec![Field::Decimal(Decimal::from_i32(4, 5, 2))]);
1974 assert!(list.get_bool(0).is_err());
1975 }
1976
1977 #[test]
1978 fn test_list_complex_accessors() {
1979 let list = make_list(vec![Field::Group(Row::new(vec![
1980 ("x".to_string(), Field::Null),
1981 ("Y".to_string(), Field::Int(2)),
1982 ]))]);
1983 assert_eq!(2, list.get_group(0).unwrap().len());
1984
1985 let list = make_list(vec![Field::ListInternal(make_list(vec![
1986 Field::Int(2),
1987 Field::Int(1),
1988 Field::Null,
1989 Field::Int(12),
1990 ]))]);
1991 assert_eq!(4, list.get_list(0).unwrap().len());
1992
1993 let list = make_list(vec![Field::MapInternal(make_map(vec![
1994 (Field::Int(1), Field::Float(1.2)),
1995 (Field::Int(2), Field::Float(4.5)),
1996 (Field::Int(3), Field::Float(2.3)),
1997 ]))]);
1998 assert_eq!(3, list.get_map(0).unwrap().len());
1999 }
2000
2001 #[test]
2002 fn test_list_complex_invalid_accessors() {
2003 let list = make_list(vec![Field::Group(Row::new(vec![
2004 ("x".to_string(), Field::Null),
2005 ("Y".to_string(), Field::Int(2)),
2006 ]))]);
2007 assert_eq!(
2008 list.get_float(0).unwrap_err().to_string(),
2009 "Parquet error: Cannot access Group as Float"
2010 );
2011
2012 let list = make_list(vec![Field::ListInternal(make_list(vec![
2013 Field::Int(2),
2014 Field::Int(1),
2015 Field::Null,
2016 Field::Int(12),
2017 ]))]);
2018 assert_eq!(
2019 list.get_float(0).unwrap_err().to_string(),
2020 "Parquet error: Cannot access ListInternal as Float"
2021 );
2022
2023 let list = make_list(vec![Field::MapInternal(make_map(vec![
2024 (Field::Int(1), Field::Float(1.2)),
2025 (Field::Int(2), Field::Float(4.5)),
2026 (Field::Int(3), Field::Float(2.3)),
2027 ]))]);
2028 assert_eq!(
2029 list.get_float(0).unwrap_err().to_string(),
2030 "Parquet error: Cannot access MapInternal as Float",
2031 );
2032 }
2033
2034 #[test]
2035 fn test_map_accessors() {
2036 let map = make_map(vec![
2038 (Field::Int(1), Field::Str("a".to_string())),
2039 (Field::Int(2), Field::Str("b".to_string())),
2040 (Field::Int(3), Field::Str("c".to_string())),
2041 (Field::Int(4), Field::Str("d".to_string())),
2042 (Field::Int(5), Field::Str("e".to_string())),
2043 ]);
2044
2045 assert_eq!(5, map.len());
2046 for i in 0..5 {
2047 assert_eq!((i + 1) as i32, map.get_keys().get_int(i).unwrap());
2048 assert_eq!(
2049 &((i as u8 + b'a') as char).to_string(),
2050 map.get_values().get_string(i).unwrap()
2051 );
2052 }
2053 }
2054
2055 #[test]
2056 #[cfg_attr(miri, ignore)] fn test_to_json_value() {
2058 assert_eq!(Field::Null.to_json_value(), Value::Null);
2059 assert_eq!(Field::Bool(true).to_json_value(), Value::Bool(true));
2060 assert_eq!(Field::Bool(false).to_json_value(), Value::Bool(false));
2061 assert_eq!(
2062 Field::Byte(1).to_json_value(),
2063 Value::Number(serde_json::Number::from(1))
2064 );
2065 assert_eq!(
2066 Field::Short(2).to_json_value(),
2067 Value::Number(serde_json::Number::from(2))
2068 );
2069 assert_eq!(
2070 Field::Int(3).to_json_value(),
2071 Value::Number(serde_json::Number::from(3))
2072 );
2073 assert_eq!(
2074 Field::Long(4).to_json_value(),
2075 Value::Number(serde_json::Number::from(4))
2076 );
2077 assert_eq!(
2078 Field::UByte(1).to_json_value(),
2079 Value::Number(serde_json::Number::from(1))
2080 );
2081 assert_eq!(
2082 Field::UShort(2).to_json_value(),
2083 Value::Number(serde_json::Number::from(2))
2084 );
2085 assert_eq!(
2086 Field::UInt(3).to_json_value(),
2087 Value::Number(serde_json::Number::from(3))
2088 );
2089 assert_eq!(
2090 Field::ULong(4).to_json_value(),
2091 Value::Number(serde_json::Number::from(4))
2092 );
2093 assert_eq!(
2094 Field::Float16(f16::from_f32(5.0)).to_json_value(),
2095 Value::Number(serde_json::Number::from_f64(5.0).unwrap())
2096 );
2097 assert_eq!(
2098 Field::Float(5.0).to_json_value(),
2099 Value::Number(serde_json::Number::from_f64(5.0).unwrap())
2100 );
2101 assert_eq!(
2102 Field::Float(5.1234).to_json_value(),
2103 Value::Number(serde_json::Number::from_f64(5.1234_f32 as f64).unwrap())
2104 );
2105 assert_eq!(
2106 Field::Double(6.0).to_json_value(),
2107 Value::Number(serde_json::Number::from_f64(6.0).unwrap())
2108 );
2109 assert_eq!(
2110 Field::Double(6.1234).to_json_value(),
2111 Value::Number(serde_json::Number::from_f64(6.1234).unwrap())
2112 );
2113 assert_eq!(
2114 Field::Str("abc".to_string()).to_json_value(),
2115 Value::String(String::from("abc"))
2116 );
2117 assert_eq!(
2118 Field::Decimal(Decimal::from_i32(4, 8, 2)).to_json_value(),
2119 Value::String(String::from("0.04"))
2120 );
2121 assert_eq!(
2122 Field::Bytes(ByteArray::from(vec![1, 2, 3])).to_json_value(),
2123 Value::String(String::from("AQID"))
2124 );
2125 assert_eq!(
2126 Field::TimestampMillis(12345678).to_json_value(),
2127 Value::String("1970-01-01 03:25:45.678 +00:00".to_string())
2128 );
2129 assert_eq!(
2130 Field::TimestampMicros(12345678901).to_json_value(),
2131 Value::String("1970-01-01 03:25:45.678901 +00:00".to_string())
2132 );
2133 assert_eq!(
2134 Field::TimeMillis(47445123).to_json_value(),
2135 Value::String(String::from("13:10:45.123"))
2136 );
2137 assert_eq!(
2138 Field::TimeMicros(47445123456).to_json_value(),
2139 Value::String(String::from("13:10:45.123456"))
2140 );
2141
2142 let fields = vec![
2143 ("X".to_string(), Field::Int(1)),
2144 ("Y".to_string(), Field::Double(2.2)),
2145 ("Z".to_string(), Field::Str("abc".to_string())),
2146 ];
2147 let row = Field::Group(Row::new(fields));
2148 assert_eq!(
2149 row.to_json_value(),
2150 serde_json::json!({"X": 1, "Y": 2.2, "Z": "abc"})
2151 );
2152
2153 let row = Field::ListInternal(make_list(vec![Field::Int(1), Field::Int(12), Field::Null]));
2154 let array = vec![
2155 Value::Number(serde_json::Number::from(1)),
2156 Value::Number(serde_json::Number::from(12)),
2157 Value::Null,
2158 ];
2159 assert_eq!(row.to_json_value(), Value::Array(array));
2160
2161 let row = Field::MapInternal(make_map(vec![
2162 (Field::Str("k1".to_string()), Field::Double(1.2)),
2163 (Field::Str("k2".to_string()), Field::Double(3.4)),
2164 (Field::Str("k3".to_string()), Field::Double(4.5)),
2165 ]));
2166 assert_eq!(
2167 row.to_json_value(),
2168 serde_json::json!({"k1": 1.2, "k2": 3.4, "k3": 4.5})
2169 );
2170 }
2171}
2172
2173#[cfg(test)]
2174mod api_tests {
2175 use super::{Row, make_list, make_map};
2176 use crate::record::Field;
2177
2178 #[test]
2179 fn test_field_visibility() {
2180 let row = Row::new(vec![(
2181 "a".to_string(),
2182 Field::Group(Row::new(vec![
2183 ("x".to_string(), Field::Null),
2184 ("Y".to_string(), Field::Int(2)),
2185 ])),
2186 )]);
2187
2188 match row.get_column_iter().next() {
2189 Some(column) => {
2190 assert_eq!("a", column.0);
2191 match column.1 {
2192 Field::Group(r) => {
2193 assert_eq!(
2194 &Row::new(vec![
2195 ("x".to_string(), Field::Null),
2196 ("Y".to_string(), Field::Int(2)),
2197 ]),
2198 r
2199 );
2200 }
2201 _ => panic!("Expected the first column to be Field::Group"),
2202 }
2203 }
2204 None => panic!("Expected at least one column"),
2205 }
2206 }
2207
2208 #[test]
2209 fn test_list_element_access() {
2210 let expected = vec![
2211 Field::Int(1),
2212 Field::Group(Row::new(vec![
2213 ("x".to_string(), Field::Null),
2214 ("Y".to_string(), Field::Int(2)),
2215 ])),
2216 ];
2217
2218 let list = make_list(expected.clone());
2219 assert_eq!(expected.as_slice(), list.elements());
2220 }
2221
2222 #[test]
2223 fn test_map_entry_access() {
2224 let expected = vec![
2225 (Field::Str("one".to_owned()), Field::Int(1)),
2226 (Field::Str("two".to_owned()), Field::Int(2)),
2227 ];
2228
2229 let map = make_map(expected.clone());
2230 assert_eq!(expected.as_slice(), map.entries());
2231 }
2232}