@@ -29,8 +29,8 @@ use vortex_array::vtable::VTable;
2929use vortex_array:: vtable:: ValidityVTable ;
3030use vortex_array:: vtable:: child_to_validity;
3131use vortex_array:: vtable:: validity_to_child;
32- use vortex_buffer:: BitBuffer ;
3332use vortex_buffer:: ByteBuffer ;
33+ use vortex_buffer:: { BitBuffer , BitBufferMut } ;
3434use vortex_error:: VortexExpect as _;
3535use vortex_error:: VortexResult ;
3636use vortex_error:: vortex_bail;
@@ -151,7 +151,8 @@ impl VTable for ByteBool {
151151 }
152152
153153 fn execute ( array : Array < Self > , _ctx : & mut ExecutionCtx ) -> VortexResult < ExecutionResult > {
154- let boolean_buffer = BitBuffer :: from ( array. as_slice ( ) ) ;
154+ // convert truthy values to set/unset bits
155+ let boolean_buffer = BitBufferMut :: from ( array. truthy_bytes ( ) ) . freeze ( ) ;
155156 let validity = array. validity ( ) ?;
156157 Ok ( ExecutionResult :: done (
157158 BoolArray :: new ( boolean_buffer, validity) . into_array ( ) ,
@@ -225,7 +226,7 @@ impl ByteBool {
225226 /// # Safety
226227 ///
227228 /// Every byte of `buffer` must be `0x00` or `0x01`. Any other byte value is
228- /// Undefined Behavior because [`ByteBoolData::as_slice `] reinterprets the buffer
229+ /// Undefined Behavior because [`ByteBoolData::truthy_bytes `] reinterprets the buffer
229230 /// as `&[bool]`, and a `bool` with any bit pattern other than 0 or 1 is UB.
230231 /// If `validity` is [`Validity::Array`], its length must equal `buffer.len()`.
231232 pub unsafe fn new_unchecked ( buffer : BufferHandle , validity : Validity ) -> ByteBoolArray {
@@ -295,7 +296,7 @@ impl ByteBoolData {
295296
296297 /// Validate that every byte of `buffer` is `0x00` or `0x01`.
297298 ///
298- /// [`ByteBoolData::as_slice `] transmutes the buffer's bytes to `&[bool]`; any byte
299+ /// [`ByteBoolData::truthy_bytes `] transmutes the buffer's bytes to `&[bool]`; any byte
299300 /// other than `0x00` or `0x01` would produce a `bool` with an invalid bit pattern,
300301 /// which is Undefined Behavior per the Rust reference.
301302 ///
@@ -345,7 +346,7 @@ impl ByteBoolData {
345346 /// # Safety
346347 ///
347348 /// Every byte of `buffer` must be `0x00` or `0x01`. Any other byte value is
348- /// Undefined Behavior because [`ByteBoolData::as_slice `] reinterprets the buffer
349+ /// Undefined Behavior because [`ByteBoolData::truthy_bytes `] reinterprets the buffer
349350 /// as `&[bool]`, and a `bool` with any bit pattern other than 0 or 1 is UB.
350351 /// If `validity` is [`Validity::Array`], its length must equal `buffer.len()`.
351352 pub unsafe fn new_unchecked ( buffer : BufferHandle , validity : Validity ) -> Self {
@@ -394,9 +395,11 @@ impl ByteBoolData {
394395 & self . buffer
395396 }
396397
397- pub fn as_slice ( & self ) -> & [ bool ] {
398- // Safety: The internal buffer contains byte-sized bools
399- unsafe { std:: mem:: transmute ( self . buffer ( ) . as_host ( ) . as_slice ( ) ) }
398+ /// Get access to the underlying 8-bit truthy values.
399+ ///
400+ /// The zero byte indicates `false`, and any non-zero byte is a `true`.
401+ pub fn truthy_bytes ( & self ) -> & [ u8 ] {
402+ self . buffer ( ) . as_host ( ) . as_slice ( )
400403 }
401404}
402405
@@ -514,7 +517,7 @@ mod tests {
514517 // SAFETY: all bytes are 0 or 1.
515518 let arr = unsafe { ByteBool :: new_unchecked ( handle, Validity :: NonNullable ) } ;
516519 assert_eq ! ( arr. len( ) , 4 ) ;
517- assert_eq ! ( arr. as_slice ( ) , & [ false , true , true , false ] ) ;
520+ assert_eq ! ( arr. truthy_bytes ( ) , & [ false , true , true , false ] ) ;
518521 }
519522
520523 #[ test]
0 commit comments