• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16004224696

01 Jul 2025 03:53PM UTC coverage: 77.952%. Remained the same
16004224696

push

github

web-flow
chore: rename error => error_out (#3708)

Signed-off-by: Alexander Droste <alexander.droste@protonmail.com>

0 of 24 new or added lines in 4 files covered. (0.0%)

42908 of 55044 relevant lines covered (77.95%)

56219.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.34
/vortex-ffi/src/array.rs
1
//! FFI interface for working with Vortex Arrays.
2
use std::ffi::{c_int, c_void};
3
use std::ptr;
4

5
use vortex::dtype::half::f16;
6
use vortex::error::{VortexExpect, VortexUnwrap, vortex_err};
7
use vortex::{Array, ToCanonical};
8

9
use crate::arc_dyn_wrapper;
10
use crate::dtype::vx_dtype;
11
use crate::error::{try_or, vx_error};
12

13
arc_dyn_wrapper!(
14
    /// Base type for all Vortex arrays.
15
    ///
16
    /// All built-in Vortex array types can be safely cast to this type to pass into functions that
17
    /// expect a generic array type. e.g.
18
    ///
19
    /// ```cpp
20
    /// auto primitive_array = vx_array_primitive_new(...);
21
    /// vx_array_len((*vx_array) primitive_array));
22
    /// ```
23
    dyn Array,
24
    vx_array
25
);
26

27
/// Get the length of the array.
28
#[unsafe(no_mangle)]
29
pub unsafe extern "C-unwind" fn vx_array_len(array: *const vx_array) -> usize {
1✔
30
    vx_array::as_ref(array).len()
1✔
31
}
1✔
32

33
/// Get the [`crate::vx_dtype`] of the array.
34
///
35
/// The returned pointer is valid as long as the array is valid.
36
#[unsafe(no_mangle)]
37
pub unsafe extern "C-unwind" fn vx_array_dtype(array: *const vx_array) -> *const vx_dtype {
1✔
38
    vx_dtype::new_ref(vx_array::as_ref(array).dtype())
1✔
39
}
1✔
40

41
#[unsafe(no_mangle)]
42
pub unsafe extern "C-unwind" fn vx_array_get_field(
×
43
    array: *const vx_array,
×
44
    index: u32,
×
NEW
45
    error_out: *mut *mut vx_error,
×
46
) -> *const vx_array {
×
NEW
47
    try_or(error_out, ptr::null(), || {
×
48
        let array = vx_array::as_ref(array);
×
49

50
        let field_array = array
×
51
            .to_struct()?
×
52
            .fields()
×
53
            .get(index as usize)
×
54
            .ok_or_else(|| vortex_err!("Field index out of bounds"))?
×
55
            .clone();
×
56

×
57
        Ok(vx_array::new(field_array))
×
58
    })
×
59
}
×
60

61
#[unsafe(no_mangle)]
62
pub unsafe extern "C-unwind" fn vx_array_slice(
×
63
    array: *const vx_array,
×
64
    start: u32,
×
65
    stop: u32,
×
NEW
66
    error_out: *mut *mut vx_error,
×
67
) -> *const vx_array {
×
68
    let array = vx_array::as_ref(array);
×
NEW
69
    try_or(error_out, ptr::null_mut(), || {
×
70
        let sliced = array.slice(start as usize, stop as usize)?;
×
71
        Ok(vx_array::new(sliced))
×
72
    })
×
73
}
×
74

75
#[unsafe(no_mangle)]
76
pub unsafe extern "C-unwind" fn vx_array_is_null(
×
77
    array: *const vx_array,
×
78
    index: u32,
×
NEW
79
    error_out: *mut *mut vx_error,
×
80
) -> bool {
×
81
    let array = vx_array::as_ref(array);
×
NEW
82
    try_or(error_out, false, || array.is_invalid(index as usize))
×
83
}
×
84

85
#[unsafe(no_mangle)]
86
pub unsafe extern "C-unwind" fn vx_array_null_count(
×
87
    array: *const vx_array,
×
NEW
88
    error_out: *mut *mut vx_error,
×
89
) -> u32 {
×
90
    let array = vx_array::as_ref(array);
×
NEW
91
    try_or(error_out, 0, || Ok(array.invalid_count()?.try_into()?))
×
92
}
×
93

94
macro_rules! ffiarray_get_ptype {
95
    ($ptype:ident) => {
96
        paste::paste! {
97
            #[unsafe(no_mangle)]
98
            pub unsafe extern "C-unwind" fn [<vx_array_get_ $ptype>](array: *const vx_array, index: u32) -> $ptype {
3✔
99
                let array = vx_array::as_ref(array);
×
100
                let value = array.scalar_at(index as usize).vortex_expect("scalar_at");
×
101
                value.as_primitive()
×
102
                    .as_::<$ptype>()
×
103
                    .vortex_expect("as_")
×
104
                    .vortex_expect("null value")
×
105
            }
×
106

×
107
            #[unsafe(no_mangle)]
×
108
            pub unsafe extern "C-unwind" fn [<vx_array_get_storage_ $ptype>](array: *const vx_array, index: u32) -> $ptype {
×
109
                let array = vx_array::as_ref(array);
×
110
                let value = array.scalar_at(index as usize).vortex_expect("scalar_at");
×
111
                value.as_extension()
×
112
                    .storage()
×
113
                    .as_primitive()
×
114
                    .as_::<$ptype>()
×
115
                    .vortex_expect("as_")
×
116
                    .vortex_expect("null value")
×
117
            }
×
118
        }
119
    };
120
}
121

122
ffiarray_get_ptype!(u8);
123
ffiarray_get_ptype!(u16);
124
ffiarray_get_ptype!(u32);
125
ffiarray_get_ptype!(u64);
126
ffiarray_get_ptype!(i8);
127
ffiarray_get_ptype!(i16);
128
ffiarray_get_ptype!(i32);
129
ffiarray_get_ptype!(i64);
130
ffiarray_get_ptype!(f16);
131
ffiarray_get_ptype!(f32);
132
ffiarray_get_ptype!(f64);
133

134
/// Write the UTF-8 string at `index` in the array into the provided destination buffer, recording
135
/// the length in `len`.
136
#[unsafe(no_mangle)]
137
pub unsafe extern "C-unwind" fn vx_array_get_utf8(
×
138
    array: *const vx_array,
×
139
    index: u32,
×
140
    dst: *mut c_void,
×
141
    len: *mut c_int,
×
142
) {
×
143
    let array = vx_array::as_ref(array);
×
144
    let value = array.scalar_at(index as usize).vortex_expect("scalar_at");
×
145
    let utf8_scalar = value.as_utf8();
×
146
    if let Some(buffer) = utf8_scalar.value() {
×
147
        let bytes = buffer.as_bytes();
×
148
        let dst = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
×
149
        dst.copy_from_slice(bytes);
×
150
        unsafe { *len = bytes.len().try_into().vortex_unwrap() };
×
151
    }
×
152
}
×
153

154
/// Write the UTF-8 string at `index` in the array into the provided destination buffer, recording
155
/// the length in `len`.
156
#[unsafe(no_mangle)]
157
pub unsafe extern "C-unwind" fn vx_array_get_binary(
×
158
    array: *const vx_array,
×
159
    index: u32,
×
160
    dst: *mut c_void,
×
161
    len: *mut c_int,
×
162
) {
×
163
    let array = vx_array::as_ref(array);
×
164
    let value = array.scalar_at(index as usize).vortex_expect("scalar_at");
×
165
    let utf8_scalar = value.as_binary();
×
166
    if let Some(bytes) = utf8_scalar.value() {
×
167
        let dst = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
×
168
        dst.copy_from_slice(&bytes);
×
169
        unsafe { *len = bytes.len().try_into().vortex_unwrap() };
×
170
    }
×
171
}
×
172

173
#[cfg(test)]
174
mod tests {
175
    use vortex::arrays::PrimitiveArray;
176
    use vortex::buffer::buffer;
177
    use vortex::validity::Validity;
178

179
    use crate::array::{vx_array, vx_array_dtype, vx_array_free, vx_array_get_i32, vx_array_len};
180
    use crate::dtype::{vx_dtype_get_variant, vx_dtype_variant};
181

182
    #[test]
183
    fn test_simple() {
1✔
184
        unsafe {
1✔
185
            let primitive = PrimitiveArray::new(buffer![1i32, 2i32, 3i32], Validity::NonNullable);
1✔
186
            let ffi_array = vx_array::new(primitive.to_array());
1✔
187

1✔
188
            assert_eq!(vx_array_len(ffi_array), 3);
1✔
189

190
            let array_dtype = vx_array_dtype(ffi_array);
1✔
191
            assert_eq!(
1✔
192
                vx_dtype_get_variant(array_dtype),
1✔
193
                vx_dtype_variant::DTYPE_PRIMITIVE
1✔
194
            );
1✔
195

196
            assert_eq!(vx_array_get_i32(ffi_array, 0), 1);
1✔
197
            assert_eq!(vx_array_get_i32(ffi_array, 1), 2);
1✔
198
            assert_eq!(vx_array_get_i32(ffi_array, 2), 3);
1✔
199

200
            vx_array_free(ffi_array);
1✔
201
        }
1✔
202
    }
1✔
203
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc