Convenience function to construct an array from a function. The function must return the number of elements it pushed into the array. It is undefined behavior if the function returns a number different to the number of elements it pushed. Returns an error if the number of elements pushed by `f` does not match the cardinality of the array as described by `dims`, or if the number of dimensions exce
(
&mut self,
dims: &[ArrayDimension],
f: F,
)
| 2511 | /// number of dimensions exceeds [`MAX_ARRAY_DIMENSIONS`], or if `f` errors. If an error |
| 2512 | /// occurs, the packer's state will be unchanged. |
| 2513 | pub unsafe fn push_array_with_unchecked<F, E>( |
| 2514 | &mut self, |
| 2515 | dims: &[ArrayDimension], |
| 2516 | f: F, |
| 2517 | ) -> Result<(), E> |
| 2518 | where |
| 2519 | F: FnOnce(&mut RowPacker) -> Result<usize, E>, |
| 2520 | E: From<InvalidArrayError>, |
| 2521 | { |
| 2522 | // Arrays are encoded as follows. |
| 2523 | // |
| 2524 | // u8 ndims |
| 2525 | // u64 dim_0 lower bound |
| 2526 | // u64 dim_0 length |
| 2527 | // ... |
| 2528 | // u64 dim_n lower bound |
| 2529 | // u64 dim_n length |
| 2530 | // u64 element data size in bytes |
| 2531 | // u8 element data, where elements are encoded in row-major order |
| 2532 | |
| 2533 | if dims.len() > usize::from(MAX_ARRAY_DIMENSIONS) { |
| 2534 | return Err(InvalidArrayError::TooManyDimensions(dims.len()).into()); |
| 2535 | } |
| 2536 | |
| 2537 | let start = self.row.data.len(); |
| 2538 | self.row.data.push(Tag::Array.into()); |
| 2539 | |
| 2540 | // Write dimension information. |
| 2541 | self.row |
| 2542 | .data |
| 2543 | .push(dims.len().try_into().expect("ndims verified to fit in u8")); |
| 2544 | for dim in dims { |
| 2545 | self.row |
| 2546 | .data |
| 2547 | .extend_from_slice(&i64::cast_from(dim.lower_bound).to_le_bytes()); |
| 2548 | self.row |
| 2549 | .data |
| 2550 | .extend_from_slice(&u64::cast_from(dim.length).to_le_bytes()); |
| 2551 | } |
| 2552 | |
| 2553 | // Write elements. |
| 2554 | let off = self.row.data.len(); |
| 2555 | self.row.data.extend_from_slice(&[0; size_of::<u64>()]); |
| 2556 | let nelements = match f(self) { |
| 2557 | Ok(nelements) => nelements, |
| 2558 | Err(e) => { |
| 2559 | self.row.data.truncate(start); |
| 2560 | return Err(e); |
| 2561 | } |
| 2562 | }; |
| 2563 | let len = u64::cast_from(self.row.data.len() - off - size_of::<u64>()); |
| 2564 | self.row.data[off..off + size_of::<u64>()].copy_from_slice(&len.to_le_bytes()); |
| 2565 | |
| 2566 | // Check that the number of elements written matches the dimension |
| 2567 | // information. |
| 2568 | let cardinality = match dims { |
| 2569 | [] => 0, |
| 2570 | // Saturate the product: a cardinality that overflows `usize` is |
no test coverage detected