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