vortex_scalar/
display.rs

1use std::fmt::{Display, Formatter};
2
3use vortex_dtype::DType;
4
5use crate::Scalar;
6
7impl Display for Scalar {
8    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
9        match self.dtype() {
10            DType::Null => write!(f, "null"),
11            DType::Bool(_) => write!(f, "{}", self.as_bool()),
12            DType::Primitive(..) => write!(f, "{}", self.as_primitive()),
13            DType::Utf8(_) => write!(f, "{}", self.as_utf8()),
14            DType::Binary(_) => write!(f, "{}", self.as_binary()),
15            DType::Struct(..) => write!(f, "{}", self.as_struct()),
16            DType::List(..) => write!(f, "{}", self.as_list()),
17            DType::Extension(_) => write!(f, "{}", self.as_extension()),
18        }
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use std::sync::Arc;
25
26    use vortex_buffer::ByteBuffer;
27    use vortex_dtype::Nullability::{NonNullable, Nullable};
28    use vortex_dtype::datetime::{DATE_ID, TIME_ID, TIMESTAMP_ID, TemporalMetadata, TimeUnit};
29    use vortex_dtype::{DType, ExtDType, ExtMetadata, PType, StructDType};
30
31    use crate::{InnerScalarValue, PValue, Scalar, ScalarValue};
32
33    const MINUTES: i32 = 60;
34    const HOURS: i32 = 60 * MINUTES;
35    const DAYS: i32 = 24 * HOURS;
36
37    #[test]
38    fn display_bool() {
39        assert_eq!(format!("{}", Scalar::from(false)), "false");
40        assert_eq!(format!("{}", Scalar::from(true)), "true");
41        assert_eq!(format!("{}", Scalar::null(DType::Bool(Nullable))), "null");
42    }
43
44    #[test]
45    fn display_primitive() {
46        assert_eq!(format!("{}", Scalar::from(0u8)), "0u8");
47        assert_eq!(format!("{}", Scalar::from(255u8)), "255u8");
48
49        assert_eq!(format!("{}", Scalar::from(0u16)), "0u16");
50        assert_eq!(format!("{}", Scalar::from(!0u16)), "65535u16");
51
52        assert_eq!(format!("{}", Scalar::from(0u32)), "0u32");
53        assert_eq!(format!("{}", Scalar::from(!0u32)), "4294967295u32");
54
55        assert_eq!(format!("{}", Scalar::from(0u64)), "0u64");
56        assert_eq!(
57            format!("{}", Scalar::from(!0u64)),
58            "18446744073709551615u64"
59        );
60
61        assert_eq!(
62            format!("{}", Scalar::null(DType::Primitive(PType::U8, Nullable))),
63            "null"
64        );
65    }
66
67    #[test]
68    fn display_utf8() {
69        assert_eq!(
70            format!("{}", Scalar::from("Hello World!")),
71            "\"Hello World!\""
72        );
73        assert_eq!(format!("{}", Scalar::null(DType::Utf8(Nullable))), "null");
74    }
75
76    #[test]
77    fn display_binary() {
78        assert_eq!(
79            format!(
80                "{}",
81                Scalar::binary(
82                    ByteBuffer::from("Hello World!".as_bytes().to_vec()),
83                    NonNullable
84                )
85            ),
86            "\"48 65 6c 6c 6f 20 57 6f 72 6c 64 21\""
87        );
88        assert_eq!(format!("{}", Scalar::null(DType::Binary(Nullable))), "null");
89    }
90
91    #[test]
92    fn display_empty_struct() {
93        fn dtype() -> DType {
94            DType::Struct(Arc::new(StructDType::new([].into(), vec![])), Nullable)
95        }
96
97        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
98
99        assert_eq!(format!("{}", Scalar::struct_(dtype(), vec![])), "{}");
100    }
101
102    #[test]
103    fn display_one_field_struct() {
104        fn dtype() -> DType {
105            DType::Struct(
106                Arc::new(StructDType::new(
107                    [Arc::from("foo")].into(),
108                    vec![DType::Primitive(PType::U32, Nullable)],
109                )),
110                Nullable,
111            )
112        }
113
114        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
115
116        assert_eq!(
117            format!(
118                "{}",
119                Scalar::struct_(dtype(), vec![Scalar::null_typed::<u32>()])
120            ),
121            "{foo: null}"
122        );
123
124        assert_eq!(
125            format!("{}", Scalar::struct_(dtype(), vec![Scalar::from(32_u32)])),
126            "{foo: 32u32}"
127        );
128    }
129
130    #[test]
131    fn display_two_field_struct() {
132        // fn dtype() -> (DType, DType, DType) {
133        let f1 = DType::Bool(Nullable);
134        let f2 = DType::Primitive(PType::U32, Nullable);
135        let dtype = DType::Struct(
136            Arc::new(StructDType::new(
137                [Arc::from("foo"), Arc::from("bar")].into(),
138                vec![f1.clone(), f2.clone()],
139            )),
140            Nullable,
141        );
142        // }
143
144        assert_eq!(format!("{}", Scalar::null(dtype.clone())), "null");
145
146        assert_eq!(
147            format!(
148                "{}",
149                Scalar::struct_(
150                    dtype.clone(),
151                    vec![Scalar::null(f1), Scalar::null(f2.clone())]
152                )
153            ),
154            "{foo: null, bar: null}"
155        );
156
157        assert_eq!(
158            format!(
159                "{}",
160                Scalar::struct_(dtype.clone(), vec![Scalar::from(true), Scalar::null(f2)])
161            ),
162            "{foo: true, bar: null}"
163        );
164
165        assert_eq!(
166            format!(
167                "{}",
168                Scalar::struct_(dtype, vec![Scalar::from(true), Scalar::from(32_u32)])
169            ),
170            "{foo: true, bar: 32u32}"
171        );
172    }
173
174    #[test]
175    fn display_time() {
176        fn dtype() -> DType {
177            DType::Extension(Arc::new(ExtDType::new(
178                TIME_ID.clone(),
179                Arc::new(DType::Primitive(PType::I32, Nullable)),
180                Some(ExtMetadata::from(TemporalMetadata::Time(TimeUnit::S))),
181            )))
182        }
183
184        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
185
186        assert_eq!(
187            format!(
188                "{}",
189                Scalar::new(
190                    dtype(),
191                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(3 * MINUTES + 25)))
192                )
193            ),
194            "00:03:25"
195        );
196    }
197
198    #[test]
199    fn display_date() {
200        fn dtype() -> DType {
201            DType::Extension(Arc::new(ExtDType::new(
202                DATE_ID.clone(),
203                Arc::new(DType::Primitive(PType::I32, Nullable)),
204                Some(ExtMetadata::from(TemporalMetadata::Date(TimeUnit::D))),
205            )))
206        }
207
208        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
209
210        assert_eq!(
211            format!(
212                "{}",
213                Scalar::new(
214                    dtype(),
215                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(25)))
216                )
217            ),
218            "1970-01-26"
219        );
220
221        assert_eq!(
222            format!(
223                "{}",
224                Scalar::new(
225                    dtype(),
226                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(365)))
227                )
228            ),
229            "1971-01-01"
230        );
231
232        assert_eq!(
233            format!(
234                "{}",
235                Scalar::new(
236                    dtype(),
237                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(365 * 4)))
238                )
239            ),
240            "1973-12-31"
241        );
242    }
243
244    #[test]
245    fn display_local_timestamp() {
246        fn dtype() -> DType {
247            DType::Extension(Arc::new(ExtDType::new(
248                TIMESTAMP_ID.clone(),
249                Arc::new(DType::Primitive(PType::I32, Nullable)),
250                Some(ExtMetadata::from(TemporalMetadata::Timestamp(
251                    TimeUnit::S,
252                    None,
253                ))),
254            )))
255        }
256
257        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
258
259        assert_eq!(
260            format!(
261                "{}",
262                Scalar::new(
263                    dtype(),
264                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(
265                        3 * DAYS + 2 * HOURS + 5 * MINUTES + 10
266                    )))
267                )
268            ),
269            "1970-01-04T02:05:10Z"
270        );
271    }
272
273    #[cfg_attr(miri, ignore)]
274    #[test]
275    fn display_zoned_timestamp() {
276        fn dtype() -> DType {
277            DType::Extension(Arc::new(ExtDType::new(
278                TIMESTAMP_ID.clone(),
279                Arc::new(DType::Primitive(PType::I64, Nullable)),
280                Some(ExtMetadata::from(TemporalMetadata::Timestamp(
281                    TimeUnit::S,
282                    Some(String::from("Pacific/Guam")),
283                ))),
284            )))
285        }
286
287        assert_eq!(format!("{}", Scalar::null(dtype())), "null");
288
289        assert_eq!(
290            format!(
291                "{}",
292                Scalar::new(
293                    dtype(),
294                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(0)))
295                )
296            ),
297            "1970-01-01T10:00:00+10:00[Pacific/Guam]"
298        );
299
300        assert_eq!(
301            format!(
302                "{}",
303                Scalar::new(
304                    dtype(),
305                    ScalarValue(InnerScalarValue::Primitive(PValue::I32(
306                        3 * DAYS + 2 * HOURS + 5 * MINUTES + 10
307                    )))
308                )
309            ),
310            "1970-01-04T12:05:10+10:00[Pacific/Guam]"
311        );
312    }
313}