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