From f325d7a71605ecfb64e9603379f7817d4e7b70b5 Mon Sep 17 00:00:00 2001 From: blaginin Date: Tue, 3 Feb 2026 14:11:43 +0000 Subject: [PATCH 1/4] `alternate` for `StructFields` Signed-off-by: blaginin --- vortex-dtype/src/struct_.rs | 79 ++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/vortex-dtype/src/struct_.rs b/vortex-dtype/src/struct_.rs index c796fdd4ce8..ba2c0fcef35 100644 --- a/vortex-dtype/src/struct_.rs +++ b/vortex-dtype/src/struct_.rs @@ -153,15 +153,49 @@ impl std::fmt::Debug for StructFields { impl Display for StructFields { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{{{}}}", - self.names() - .iter() - .zip(self.fields()) - .map(|(n, dt)| format!("{n}={dt}")) - .join(", ") - ) + if f.alternate() { + self.fmt_indented(f, 0) + } else { + write!( + f, + "{{{}}}", + self.names() + .iter() + .zip(self.fields()) + .map(|(n, dt)| format!("{n}={dt}")) + .join(", ") + ) + } + } +} + +impl StructFields { + fn fmt_indented(&self, f: &mut Formatter<'_>, depth: usize) -> std::fmt::Result { + let indent = " ".repeat(depth); + let inner_indent = " ".repeat(depth + 1); + + writeln!(f, "{{")?; + for (i, (name, dtype)) in self.names().iter().zip(self.fields()).enumerate() { + if i > 0 { + writeln!(f, ",")?; + } + write!(f, "{inner_indent}{name}=")?; + Self::fmt_dtype_indented(f, &dtype, depth + 1)?; + } + if !self.names().is_empty() { + writeln!(f)?; + } + write!(f, "{indent}}}") + } + + fn fmt_dtype_indented(f: &mut Formatter<'_>, dtype: &DType, depth: usize) -> std::fmt::Result { + match dtype { + DType::Struct(sf, nullability) => { + sf.fmt_indented(f, depth)?; + write!(f, "{nullability}") + } + _ => write!(f, "{dtype}"), + } } } @@ -412,6 +446,7 @@ where #[cfg(test)] mod test { + use insta::assert_snapshot; use itertools::Itertools; use crate::FieldNames; @@ -537,9 +572,33 @@ mod test { ("id", DType::Primitive(PType::U64, Nullability::NonNullable)), ("data", DType::Struct(fields, Nullability::Nullable)), ]); - assert_eq!( + assert_snapshot!( nested.to_string(), "{id=u64, data={name=utf8, age=i32?, active=bool}?}" ); } + + #[test] + fn test_display_alternate() { + let inner = StructFields::from_iter([ + ("street", DType::Utf8(Nullability::NonNullable)), + ("city", DType::Utf8(Nullability::Nullable)), + ]); + let fields = StructFields::from_iter([ + ("name", DType::Utf8(Nullability::NonNullable)), + ("age", DType::Primitive(PType::I32, Nullability::Nullable)), + ("address", DType::Struct(inner, Nullability::Nullable)), + ]); + + assert_snapshot!(format!("{fields:#}"), @" + { + name=utf8, + age=i32?, + address={ + street=utf8, + city=utf8? + }? + } + "); + } } From 334166fb35dc43e607a00537f1d2893954dcd012 Mon Sep 17 00:00:00 2001 From: blaginin Date: Tue, 3 Feb 2026 15:42:07 +0000 Subject: [PATCH 2/4] @ Signed-off-by: blaginin --- vortex-dtype/src/struct_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vortex-dtype/src/struct_.rs b/vortex-dtype/src/struct_.rs index ba2c0fcef35..603e9207f7a 100644 --- a/vortex-dtype/src/struct_.rs +++ b/vortex-dtype/src/struct_.rs @@ -574,7 +574,7 @@ mod test { ]); assert_snapshot!( nested.to_string(), - "{id=u64, data={name=utf8, age=i32?, active=bool}?}" + @"{id=u64, data={name=utf8, age=i32?, active=bool}?}" ); } From 58860779c94c4f2446ad0ef8677f8d9fa8df1ec9 Mon Sep 17 00:00:00 2001 From: blaginin Date: Wed, 4 Feb 2026 13:57:10 +0000 Subject: [PATCH 3/4] nested + list Signed-off-by: blaginin --- vortex-dtype/src/struct_.rs | 45 ++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/vortex-dtype/src/struct_.rs b/vortex-dtype/src/struct_.rs index 603e9207f7a..52cf930149a 100644 --- a/vortex-dtype/src/struct_.rs +++ b/vortex-dtype/src/struct_.rs @@ -194,6 +194,16 @@ impl StructFields { sf.fmt_indented(f, depth)?; write!(f, "{nullability}") } + DType::List(inner, nullability) => { + write!(f, "list(")?; + Self::fmt_dtype_indented(f, inner, depth)?; + write!(f, "){nullability}") + } + DType::FixedSizeList(inner, size, nullability) => { + write!(f, "fixed_size_list(")?; + Self::fmt_dtype_indented(f, inner, depth)?; + write!(f, ")[{size}]{nullability}") + } _ => write!(f, "{dtype}"), } } @@ -446,6 +456,7 @@ where #[cfg(test)] mod test { + use std::sync::Arc; use insta::assert_snapshot; use itertools::Itertools; @@ -580,14 +591,26 @@ mod test { #[test] fn test_display_alternate() { - let inner = StructFields::from_iter([ + let city = DType::Struct( + StructFields::from_iter([ + ("name", DType::Utf8(Nullability::NonNullable)), + ("id", DType::Primitive(PType::U32, Nullability::Nullable)), + ]), + Nullability::NonNullable, + ); + + let address = DType::Struct(StructFields::from_iter([ ("street", DType::Utf8(Nullability::NonNullable)), - ("city", DType::Utf8(Nullability::Nullable)), - ]); + ("city", city), + ]), Nullability::Nullable); + + let list = DType::List(Arc::new(address.clone()), Nullability::NonNullable); + let fields = StructFields::from_iter([ ("name", DType::Utf8(Nullability::NonNullable)), ("age", DType::Primitive(PType::I32, Nullability::Nullable)), - ("address", DType::Struct(inner, Nullability::Nullable)), + ("address", address), + ("past_addresses", list), ]); assert_snapshot!(format!("{fields:#}"), @" @@ -596,8 +619,18 @@ mod test { age=i32?, address={ street=utf8, - city=utf8? - }? + city={ + name=utf8, + id=u32? + } + }?, + past_addresses=list({ + street=utf8, + city={ + name=utf8, + id=u32? + } + }?) } "); } From da9a5f6f34c27022504e17a3fe84fc1b0892f836 Mon Sep 17 00:00:00 2001 From: blaginin Date: Wed, 4 Feb 2026 16:50:39 +0000 Subject: [PATCH 4/4] nightly Signed-off-by: blaginin --- vortex-dtype/src/struct_.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/vortex-dtype/src/struct_.rs b/vortex-dtype/src/struct_.rs index 52cf930149a..51140eb2105 100644 --- a/vortex-dtype/src/struct_.rs +++ b/vortex-dtype/src/struct_.rs @@ -457,6 +457,7 @@ where #[cfg(test)] mod test { use std::sync::Arc; + use insta::assert_snapshot; use itertools::Itertools; @@ -599,10 +600,13 @@ mod test { Nullability::NonNullable, ); - let address = DType::Struct(StructFields::from_iter([ - ("street", DType::Utf8(Nullability::NonNullable)), - ("city", city), - ]), Nullability::Nullable); + let address = DType::Struct( + StructFields::from_iter([ + ("street", DType::Utf8(Nullability::NonNullable)), + ("city", city), + ]), + Nullability::Nullable, + ); let list = DType::List(Arc::new(address.clone()), Nullability::NonNullable);