Skip to content

Commit 8602539

Browse files
Make element_sizes return Result, default to Err (#80)
The default element_sizes now returns Err("unimplemented") instead of silently accepting any byte length. This ensures that validate rejects data for types that haven't implemented element_sizes, rather than passing validation and producing garbage from from_store. Types that override element_sizes push their sizes and return Ok(()). The derive macro already generates this automatically. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e4bc02a commit 8602539

File tree

6 files changed

+25
-19
lines changed

6 files changed

+25
-19
lines changed

src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ pub mod common {
665665
///
666666
/// Implementors should override this to report their actual element sizes.
667667
/// For example, `&[u32]` pushes `4`, while a tuple delegates to each field.
668-
/// The default implementation pushes `1` for each slice (accepting any byte length).
669-
fn element_sizes(sizes: &mut Vec<usize>) {
670-
for _ in 0..Self::SLICE_COUNT {
671-
sizes.push(1);
672-
}
668+
/// The default returns `Err`, so that [`validate`](Self::validate) rejects
669+
/// data for types that have not implemented this method.
670+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
671+
let _ = sizes;
672+
Err(format!("element_sizes not implemented for this type (SLICE_COUNT = {})", Self::SLICE_COUNT))
673673
}
674674
/// Validates that the given slices are compatible with this type.
675675
///
@@ -683,7 +683,7 @@ pub mod common {
683683
return Err(format!("expected {} slices but got {}", Self::SLICE_COUNT, slices.len()));
684684
}
685685
let mut sizes = Vec::new();
686-
Self::element_sizes(&mut sizes);
686+
Self::element_sizes(&mut sizes)?;
687687
for (i, elem_size) in sizes.iter().enumerate() {
688688
let (words, tail) = &slices[i];
689689
let byte_len = words.len() * 8 - ((8 - *tail as usize) % 8);

src/primitive.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ macro_rules! implement_columnable {
3535
let trim = ((8 - tail as usize) % 8) / std::mem::size_of::<$index_type>();
3636
all.get(..all.len().wrapping_sub(trim)).unwrap_or(&[])
3737
}
38-
fn element_sizes(sizes: &mut Vec<usize>) {
38+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
3939
sizes.push(std::mem::size_of::<$index_type>());
40+
Ok(())
4041
}
4142
}
4243
impl<'a, const N: usize> crate::AsBytes<'a> for &'a [[$index_type; N]] {
@@ -60,8 +61,9 @@ macro_rules! implement_columnable {
6061
let trim = ((8 - tail as usize) % 8) / (std::mem::size_of::<$index_type>() * N);
6162
all.get(..all.len().wrapping_sub(trim)).unwrap_or(&[])
6263
}
63-
fn element_sizes(sizes: &mut Vec<usize>) {
64+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
6465
sizes.push(std::mem::size_of::<$index_type>() * N);
66+
Ok(())
6567
}
6668
}
6769
)* }

src/string.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ impl<'a, BC: crate::FromBytes<'a>, VC: crate::FromBytes<'a>> crate::FromBytes<'a
109109
values: VC::from_store(store, offset),
110110
}
111111
}
112-
fn element_sizes(sizes: &mut Vec<usize>) {
113-
BC::element_sizes(sizes);
114-
VC::element_sizes(sizes);
112+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
113+
BC::element_sizes(sizes)?;
114+
VC::element_sizes(sizes)?;
115+
Ok(())
115116
}
116117
}
117118

src/sums.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -860,11 +860,12 @@ pub mod discriminant {
860860
let offset_field = crate::FromBytes::from_store(store, offset);
861861
Self { tag, count, variant, offset: offset_field }
862862
}
863-
fn element_sizes(sizes: &mut Vec<usize>) {
863+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
864864
sizes.push(8); // tag
865865
sizes.push(8); // count
866-
<&[u8]>::element_sizes(sizes);
867-
<&[u64]>::element_sizes(sizes);
866+
<&[u8]>::element_sizes(sizes)?;
867+
<&[u64]>::element_sizes(sizes)?;
868+
Ok(())
868869
}
869870
}
870871

src/tuple.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ macro_rules! tuple_impl {
7979
$(let $name = $name::from_store(store, offset);)*
8080
($($name,)*)
8181
}
82-
fn element_sizes(sizes: &mut Vec<usize>) {
83-
$($name::element_sizes(sizes);)*
82+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
83+
$($name::element_sizes(sizes)?;)*
84+
Ok(())
8485
}
8586
}
8687

src/vector.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ impl<'a, TC: crate::FromBytes<'a>, BC: crate::FromBytes<'a>> crate::FromBytes<'a
140140
values: TC::from_store(store, offset),
141141
}
142142
}
143-
fn element_sizes(sizes: &mut Vec<usize>) {
144-
BC::element_sizes(sizes);
145-
TC::element_sizes(sizes);
143+
fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
144+
BC::element_sizes(sizes)?;
145+
TC::element_sizes(sizes)?;
146+
Ok(())
146147
}
147148
}
148149

0 commit comments

Comments
 (0)