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