parquet_variant/
utils.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17use std::{array::TryFromSliceError, ops::Range, str};
18
19use arrow_schema::ArrowError;
20
21use std::fmt::Debug;
22use std::slice::SliceIndex;
23
24#[inline]
25pub(crate) fn slice_from_slice<I: SliceIndex<[u8]> + Clone + Debug>(
26    bytes: &[u8],
27    index: I,
28) -> Result<&I::Output, ArrowError> {
29    bytes.get(index.clone()).ok_or_else(|| {
30        ArrowError::InvalidArgumentError(format!(
31            "Tried to extract byte(s) {index:?} from {}-byte buffer",
32            bytes.len(),
33        ))
34    })
35}
36pub(crate) fn array_from_slice<const N: usize>(
37    bytes: &[u8],
38    offset: usize,
39) -> Result<[u8; N], ArrowError> {
40    let bytes = slice_from_slice(bytes, offset..offset + N)?;
41    bytes.try_into().map_err(map_try_from_slice_error)
42}
43
44/// To be used in `map_err` when unpacking an integer from a slice of bytes.
45pub(crate) fn map_try_from_slice_error(e: TryFromSliceError) -> ArrowError {
46    ArrowError::InvalidArgumentError(e.to_string())
47}
48
49pub(crate) fn first_byte_from_slice(slice: &[u8]) -> Result<&u8, ArrowError> {
50    slice
51        .first()
52        .ok_or_else(|| ArrowError::InvalidArgumentError("Received empty bytes".to_string()))
53}
54
55/// Helper to get a &str from a slice based on range, if it's valid or an error otherwise
56pub(crate) fn string_from_slice(slice: &[u8], range: Range<usize>) -> Result<&str, ArrowError> {
57    str::from_utf8(slice_from_slice(slice, range)?)
58        .map_err(|_| ArrowError::InvalidArgumentError("invalid UTF-8 string".to_string()))
59}