1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use ;
/// Attempts to reinterpret a byte slice as a slice of `T`, falling back to copying if alignment fails.
///
/// This function enables efficient, zero-copy parsing of binary data into typed slices (e.g., `[f32]`)
/// by using `slice::align_to::<T>()`, which reinterprets `&[u8]` as `&[T]` if alignment and size match.
///
/// If the memory is not correctly aligned for `T`, or if the total byte length is not a multiple of
/// `size_of::<T>()`, the function falls back to an owned `Vec<T>` by manually parsing each fixed-size chunk.
///
/// # Type Parameters
/// - `T`: Target type to reinterpret or decode from little-endian bytes (e.g., `f32`, `u32`)
/// - `N`: Fixed byte size of each element, must be equal to `size_of::<T>()`
///
/// # Arguments
/// - `bytes`: Raw input byte buffer
/// - `from_le_bytes`: Conversion function for `[u8; N]` into `T` (e.g., `f32::from_le_bytes`)
///
/// # Returns
/// A [`Cow<[T]>`] that:
/// - Borrows the original memory if alignment and size are compatible
/// - Allocates a new vector if fallback decoding is required
///
/// # Panics
/// - If `mem::size_of::<T>() != N`
/// - If fallback path is triggered but the input length is not a multiple of `N`
///
/// # Safety
/// The `align_to::<T>()` call is marked `unsafe` because it performs a type cast from `u8` to `T`.
/// Rust requires that:
/// - The starting address must be aligned to `align_of::<T>()`
/// - The total size of the aligned region must be a multiple of `size_of::<T>()`
///
/// We guard this by checking that `prefix` and `suffix` are empty before returning the borrowed slice.
/// If those checks fail, we instead decode manually and safely.
///
/// # Example
/// ```rust
/// use std::borrow::Cow;
/// let raw = &[0x00, 0x00, 0x80, 0x3f]; // f32 value = 1.0
/// let result: Cow<[f32]> = simd_r_drive::utils::align_or_copy::<f32, 4>(raw, f32::from_le_bytes);
/// assert_eq!(result[0], 1.0);
/// ```