cuprate_cryptonight/
util.rs

1/// Extracts a fixed-size subarray from an array, slice, or vector of any type.
2/// No copy is made.
3///
4/// # Parameters
5/// - `array`: Input array, slice, or vector of values.
6/// - `start`: Starting index of the subarray.
7///
8/// # Returns
9/// A reference to a fixed-size subarray of type `[U; LEN]`.
10///
11/// # Panics
12/// Panics if `start + LEN > array.as_ref().len()`.
13#[inline]
14pub(crate) fn subarray<T: AsRef<[U]> + ?Sized, U, const LEN: usize>(
15    array: &T,
16    start: usize,
17) -> &[U; LEN] {
18    array.as_ref()[start..start + LEN].try_into().unwrap()
19}
20
21/// Creates a new fixed-size array copying the elements from the specified subarray
22/// of a parent array, slice, or vector.
23///
24/// # Parameters
25/// - `array`: Input array, slice, or vector of copyable values.
26/// - `start`: Starting index of the subarray.
27///
28/// # Returns
29/// A new fixed-size array of type `[u8; LEN]`.
30///
31/// # Panics
32/// Panics if `start + LEN > array.as_ref().len()`.
33#[inline]
34pub(crate) fn subarray_copy<T: AsRef<[U]> + ?Sized, U: Copy, const LEN: usize>(
35    array: &T,
36    start: usize,
37) -> [U; LEN] {
38    array.as_ref()[start..start + LEN].try_into().unwrap()
39}
40
41/// Extracts a mutable subarray from an array, slice, or vector of any type.
42/// Changes to the subarray will be reflected in the original array.
43///
44/// # Parameters
45/// - `array`: Input array, slice, or vector of values.
46/// - `start`: Starting index of the subarray.
47///
48/// # Returns
49/// A mutable reference to a fixed-size subarray of type `[U; LEN]`.
50///
51/// # Panics
52/// Panics if `start + LEN > array.as_mut().len()`.
53#[inline]
54pub(crate) fn subarray_mut<T: AsMut<[U]> + ?Sized, U, const LEN: usize>(
55    array: &mut T,
56    start: usize,
57) -> &mut [U; LEN] {
58    (&mut array.as_mut()[start..start + LEN])
59        .try_into()
60        .unwrap()
61}
62
63#[cfg(test)]
64pub(crate) fn hex_to_array<const N: usize>(hex: &str) -> [u8; N] {
65    assert_eq!(
66        hex.len(),
67        N * 2,
68        "Hex string length must be twice the array size"
69    );
70    hex::decode(hex).unwrap().try_into().unwrap()
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_subarray() {
79        let array = [1_u8, 2, 3, 4, 5];
80        let sub: &[u8; 3] = subarray(&array, 1);
81        assert_eq!(sub, &[2, 3, 4]);
82        assert!(std::ptr::eq(&array[1], &sub[0])); // same memory, not copy
83    }
84
85    #[test]
86    fn test_subarray_copy() {
87        let mut array = [1_u8, 2, 3, 4, 5];
88        let sub_copied: [u8; 3] = subarray_copy(&array, 1);
89        assert_eq!(sub_copied, [2, 3, 4]);
90        array[1] = 10;
91        assert_eq!(sub_copied, [2, 3, 4]); // copy, not affected
92    }
93
94    #[test]
95    fn test_subarray_mut() {
96        let mut array = [1_u8, 2, 3, 4, 5];
97        let sub: &mut [u8; 2] = subarray_mut(&mut array, 1);
98        assert_eq!(sub, &[2_u8, 3]);
99        sub[0] = 10;
100        assert_eq!(array, [1_u8, 10, 3, 4, 5]); // original array modified
101    }
102    #[test]
103    #[should_panic(expected = "range end index 4 out of range for slice of length 1")]
104    fn subarray_panic() {
105        let array = [1_u8];
106        let _: &[u8; 3] = subarray(&array, 1);
107    }
108
109    #[test]
110    #[should_panic(expected = "range end index 4 out of range for slice of length 1")]
111    fn subarray_copy_panic() {
112        let array = [1_u8];
113        let _: [u8; 3] = subarray_copy(&array, 1);
114    }
115
116    #[test]
117    #[should_panic(expected = "range end index 4 out of range for slice of length 1")]
118    fn subarray_mut_panic() {
119        let mut array = [1_u8];
120        let _: &mut [u8; 3] = subarray_mut(&mut array, 1);
121    }
122}