diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs index 75b86fd..e2b7398 100644 --- a/src/sequence/mod.rs +++ b/src/sequence/mod.rs @@ -82,14 +82,30 @@ impl<'a> Sequence<'a> { /// and between `1` and `32` bytes (inclusive) if `is_signed` is `false`. pub fn from_raw_parts(slice: &'a [T], is_signed: bool) -> Self { let element_size = core::mem::size_of::(); + Self::from_raw_parts_with_size(slice, element_size, is_signed) + } + + /// Converts a slice of any type to a Sequence by calling `from_raw_parts` on it. + /// + /// The `is_signed` parameter is used to determine whether the data is interpreted as a signed value or not. + /// The `element_size` parameter specifies the size of each element in bytes. + pub fn from_raw_parts_with_size( + slice: &'a [T], + element_size: usize, + is_signed: bool, + ) -> Self { + assert!(element_size > 0); if is_signed { - assert!(element_size > 0); assert!(element_size <= 16); } else { - assert!(element_size > 0); 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, diff --git a/src/sequence/test.rs b/src/sequence/test.rs index 427fb0e..c2d1f6c 100644 --- a/src/sequence/test.rs +++ b/src/sequence/test.rs @@ -190,6 +190,30 @@ fn we_can_convert_a_slice_of_scalars_to_a_sequence_with_correct_data() { ); } +#[test] +fn we_can_convert_a_slice_of_fixed_size_binary_to_a_sequence_with_correct_data() { + let element_size = 4; + let s = [ + [0x01u8, 0x02u8, 0x03u8, 0x04u8], + [0x05u8, 0x06u8, 0x07u8, 0x08u8], + [0x09u8, 0x0Au8, 0x0Bu8, 0x0Cu8], + ]; + + let d = Sequence::from_raw_parts_with_size(&s[..], element_size, false); + + assert_eq!(d.element_size, element_size); + assert_eq!(d.len(), 3); + + assert_eq!( + d.data_slice, + [ + 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0Au8, 0x0Bu8, + 0x0Cu8 + ] + ); + assert!(!d.is_signed); +} + #[test] #[cfg(feature = "arkworks")] fn we_can_convert_a_slice_of_arkworks_bigint_to_the_same_values_as_scalars() {