diff --git a/inout/src/inout.rs b/inout/src/inout.rs index 6d0a05f0..53be1ec8 100644 --- a/inout/src/inout.rs +++ b/inout/src/inout.rs @@ -1,6 +1,6 @@ use crate::InOutBuf; -use core::{marker::PhantomData, ptr}; -use hybrid_array::{Array, ArraySize}; +use core::{marker::PhantomData, ops::Mul, ptr}; +use hybrid_array::{Array, ArraySize, typenum::Prod}; /// Custom pointer type which contains one immutable (input) and one mutable /// (output) pointer, which are either equal or non-overlapping. @@ -151,6 +151,28 @@ impl<'inp, 'out, T, N: ArraySize> InOut<'inp, 'out, Array> { } } +impl<'inp, 'out, T, N, M> From>>> + for Array>, M> +where + N: ArraySize, + M: ArraySize, + N: Mul, + Prod: ArraySize, +{ + fn from(buf: InOut<'inp, 'out, Array>>) -> Self { + let in_ptr: *const Array = buf.in_ptr.cast(); + let out_ptr: *mut Array = buf.out_ptr.cast(); + + Array::from_fn(|i| unsafe { + InOut { + in_ptr: in_ptr.add(i), + out_ptr: out_ptr.add(i), + _pd: PhantomData, + } + }) + } +} + impl InOut<'_, '_, Array> { /// XOR `data` with values behind the input slice and write /// result to the output slice. diff --git a/inout/tests/split-inout.rs b/inout/tests/split-inout.rs new file mode 100644 index 00000000..c637fb92 --- /dev/null +++ b/inout/tests/split-inout.rs @@ -0,0 +1,34 @@ +use hybrid_array::{ + Array, + sizes::{U2, U4, U8}, +}; +use inout::{InOut, InOutBuf}; + +#[test] +fn test_split() { + let mut buf = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let inout: InOutBuf<'_, '_, u8> = buf.as_mut_slice().into(); + + let expected: Vec<&[u8]> = vec![ + &[1, 2], + &[3, 4], + &[5, 6], + &[7, 8], + &[9, 10], + &[11, 12], + &[13, 14], + &[15, 16], + ]; + let mut expected = expected.into_iter(); + + let (blocks, _tail) = inout.into_chunks::(); + for block in blocks.into_iter() { + type SubBlock = Array; + + let subblocks = Array::, U4>::from(block); + + for subblock in subblocks { + assert_eq!(Some(subblock.get_in().as_slice()), expected.next()); + } + } +}