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