Skip to main content

vortex_array/scalar/
display.rs

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