use blitzar_sys::sxt_sequence_descriptor;
#[derive(Copy, Clone)]
pub struct Sequence<'a> {
data_slice: &'a [u8],
element_size: usize,
is_signed: bool,
}
impl<'a> Sequence<'a> {
pub fn len(&self) -> usize {
self.data_slice.len() / self.element_size
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn from_raw_parts<T>(slice: &'a [T], is_signed: bool) -> Self {
let element_size = core::mem::size_of::<T>();
Self::from_raw_parts_with_size(slice, element_size, is_signed)
}
pub fn from_raw_parts_with_size<T>(
slice: &'a [T],
element_size: usize,
is_signed: bool,
) -> Self {
assert!(element_size > 0);
if is_signed {
assert!(element_size <= 16);
} else {
assert!(element_size <= 32);
}
let len = std::mem::size_of_val(slice);
assert_eq!(
len % element_size,
0,
"raw data length should be a multiple of element size"
);
let data_slice = unsafe { core::slice::from_raw_parts(slice.as_ptr() as *const u8, len) };
Sequence {
data_slice,
element_size,
is_signed,
}
}
}
impl From<&Sequence<'_>> for sxt_sequence_descriptor {
fn from(other: &Sequence<'_>) -> Self {
sxt_sequence_descriptor {
element_nbytes: other.element_size as u8,
n: other.len() as u64,
data: other.data_slice.as_ptr(),
is_signed: other.is_signed as ::std::os::raw::c_int,
}
}
}
impl<'a, T> From<&'a Vec<T>> for Sequence<'a>
where
Sequence<'a>: From<&'a [T]>,
{
fn from(value: &'a Vec<T>) -> Self {
value.as_slice().into()
}
}
impl<'a, T> From<&'a mut [T]> for Sequence<'a>
where
Sequence<'a>: From<&'a [T]>,
{
fn from(value: &'a mut [T]) -> Self {
value[..].into()
}
}
macro_rules! impl_dense_sequence_for_unsigned {
($($t:ty),*) => {
$(
impl<'a> From<&'a [$t]> for Sequence<'a> {
fn from(other: &'a [$t]) -> Self {
Sequence::from_raw_parts(other, false)
}
}
)*
};
}
impl_dense_sequence_for_unsigned!(
bool,
u8,
u16,
u32,
u64,
u128,
curve25519_dalek::scalar::Scalar
);
macro_rules! impl_dense_sequence_for_signed {
($($t:ty),*) => {
$(
impl<'a> From<&'a [$t]> for Sequence<'a> {
fn from(other: &'a [$t]) -> Self {
Sequence::from_raw_parts(other, true)
}
}
)*
};
}
impl_dense_sequence_for_signed!(i8, i16, i32, i64, i128);
macro_rules! impl_dense_sequence_for_unsigned_array {
($($t:ty),*) => {
$(
impl<'a, const N:usize> From<&'a [[$t;N]]> for Sequence<'a> {
fn from(other: &'a [[$t;N]]) -> Self {
Sequence::from_raw_parts(other, false)
}
}
)*
};
}
impl_dense_sequence_for_unsigned_array!(bool, u8, u16, u32, u64, u128);
#[cfg(feature = "arkworks")]
impl<'a, const N: usize> From<&'a [ark_ff::BigInt<N>]> for Sequence<'a> {
fn from(other: &'a [ark_ff::BigInt<N>]) -> Self {
Sequence::from_raw_parts(other, false)
}
}
#[cfg(test)]
mod test;