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