Skip to content

Commit 7e5f523

Browse files
authored
impl From<ScalarBuffer<T>> for Vec<T> (#5518)
* impl `From<ScalarBuffer<T>>` for `Vec<T>` * Remove layout test, prevented by `miri`
1 parent ae42b3b commit 7e5f523

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

arrow-buffer/src/buffer/scalar.rs

+52
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ impl<T: ArrowNativeType> From<Vec<T>> for ScalarBuffer<T> {
160160
}
161161
}
162162

163+
impl<T: ArrowNativeType> From<ScalarBuffer<T>> for Vec<T> {
164+
fn from(value: ScalarBuffer<T>) -> Self {
165+
value
166+
.buffer
167+
.into_vec()
168+
.unwrap_or_else(|buffer| buffer.typed_data::<T>().into())
169+
}
170+
}
171+
163172
impl<T: ArrowNativeType> From<BufferBuilder<T>> for ScalarBuffer<T> {
164173
fn from(mut value: BufferBuilder<T>) -> Self {
165174
let len = value.len();
@@ -208,6 +217,8 @@ impl<T: ArrowNativeType> PartialEq<ScalarBuffer<T>> for Vec<T> {
208217

209218
#[cfg(test)]
210219
mod tests {
220+
use std::{ptr::NonNull, sync::Arc};
221+
211222
use super::*;
212223

213224
#[test]
@@ -284,4 +295,45 @@ mod tests {
284295
let scalar_buffer = ScalarBuffer::from(buffer_builder);
285296
assert_eq!(scalar_buffer.as_ref(), input);
286297
}
298+
299+
#[test]
300+
fn into_vec() {
301+
let input = vec![1u8, 2, 3, 4];
302+
303+
// No copy
304+
let input_buffer = Buffer::from_vec(input.clone());
305+
let input_ptr = input_buffer.as_ptr();
306+
let input_len = input_buffer.len();
307+
let scalar_buffer = ScalarBuffer::<u8>::new(input_buffer, 0, input_len);
308+
let vec = Vec::from(scalar_buffer);
309+
assert_eq!(vec.as_slice(), input.as_slice());
310+
assert_eq!(vec.as_ptr(), input_ptr);
311+
312+
// Custom allocation - makes a copy
313+
let mut input_clone = input.clone();
314+
let input_ptr = NonNull::new(input_clone.as_mut_ptr()).unwrap();
315+
let dealloc = Arc::new(());
316+
let buffer =
317+
unsafe { Buffer::from_custom_allocation(input_ptr, input_clone.len(), dealloc as _) };
318+
let scalar_buffer = ScalarBuffer::<u8>::new(buffer, 0, input.len());
319+
let vec = Vec::from(scalar_buffer);
320+
assert_eq!(vec, input.as_slice());
321+
assert_ne!(vec.as_ptr(), input_ptr.as_ptr());
322+
323+
// Offset - makes a copy
324+
let input_buffer = Buffer::from_vec(input.clone());
325+
let input_ptr = input_buffer.as_ptr();
326+
let input_len = input_buffer.len();
327+
let scalar_buffer = ScalarBuffer::<u8>::new(input_buffer, 1, input_len - 1);
328+
let vec = Vec::from(scalar_buffer);
329+
assert_eq!(vec.as_slice(), &input[1..]);
330+
assert_ne!(vec.as_ptr(), input_ptr);
331+
332+
// Inner buffer Arc ref count != 0 - makes a copy
333+
let buffer = Buffer::from_slice_ref(input.as_slice());
334+
let scalar_buffer = ScalarBuffer::<u8>::new(buffer, 0, input.len());
335+
let vec = Vec::from(scalar_buffer);
336+
assert_eq!(vec, input.as_slice());
337+
assert_ne!(vec.as_ptr(), input.as_ptr());
338+
}
287339
}

0 commit comments

Comments
 (0)