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