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