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