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