Coverage Report

Created: 2025-09-04 06:37

/src/adhd/audio_processor/src/slice_cast.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
/// Trait to support slice casting.
6
pub trait SliceCast<'a> {
7
    /// Cast the slice.
8
    /// This is a "view" cast. The underlying memory is unchanged.
9
    /// Panics if the length or alignment is invalid for `T`.
10
    fn cast<T: Sized>(self) -> &'a mut [T];
11
}
12
13
impl<'a, T> SliceCast<'a> for &'a mut [T]
14
where
15
    T: Sized,
16
{
17
0
    fn cast<U: Sized>(self) -> &'a mut [U] {
18
0
        let bytes = std::mem::size_of::<T>() * self.len();
19
0
        if bytes % std::mem::size_of::<U>() != 0 {
20
0
            panic!(
21
0
                "Cannot convert {} x {} to {}",
22
0
                self.len(),
23
0
                std::any::type_name::<T>(),
24
0
                std::any::type_name::<U>(),
25
0
            );
26
0
        }
27
0
28
0
        unsafe {
29
0
            if self.as_ptr() as usize % std::mem::align_of::<U>() != 0 {
30
0
                panic!(
31
0
                    "Pointer 0x{:x} is misaligned for {}",
32
0
                    self.as_ptr() as usize,
33
0
                    std::any::type_name::<U>(),
34
0
                )
35
0
            }
36
0
37
0
            std::slice::from_raw_parts_mut(
38
0
                self.as_mut_ptr().cast::<U>(),
39
0
                bytes / std::mem::size_of::<U>(),
40
0
            )
41
0
        }
42
0
    }
Unexecuted instantiation: <&mut [f32] as audio_processor::slice_cast::SliceCast>::cast::<u8>
Unexecuted instantiation: <&mut [u8] as audio_processor::slice_cast::SliceCast>::cast::<f32>
Unexecuted instantiation: <&mut [f32] as audio_processor::slice_cast::SliceCast>::cast::<u8>
Unexecuted instantiation: <&mut [u8] as audio_processor::slice_cast::SliceCast>::cast::<f32>
43
}
44
45
#[cfg(test)]
46
mod tests {
47
    use super::SliceCast;
48
49
    #[test]
50
    fn byte_to_u32() {
51
        let mut arr = [1u8, 2, 3, 4, 5, 6, 7, 8];
52
53
        let u32slice: &mut [u32] = (&mut arr[..]).cast();
54
        assert_eq!(
55
            u32slice,
56
            [
57
                u32::from_ne_bytes([1u8, 2, 3, 4]),
58
                u32::from_ne_bytes([5u8, 6, 7, 8]),
59
            ]
60
        );
61
62
        u32slice[0] = 0x12345678;
63
        u32slice[1] = 0x23456789;
64
65
        assert_eq!(
66
            &arr[..],
67
            0x12345678u32
68
                .to_ne_bytes()
69
                .into_iter()
70
                .chain(0x23456789u32.to_ne_bytes())
71
                .collect::<Vec<u8>>()
72
        );
73
    }
74
75
    #[test]
76
    fn u32_to_byte() {
77
        let mut arr = [0x12345678u32, 0x23456789u32];
78
79
        let u8slice: &mut [u8] = (&mut arr[..]).cast();
80
        assert_eq!(
81
            u8slice,
82
            0x12345678u32
83
                .to_ne_bytes()
84
                .into_iter()
85
                .chain(0x23456789u32.to_ne_bytes())
86
                .collect::<Vec<u8>>()
87
        );
88
89
        for (i, x) in u8slice.iter_mut().enumerate() {
90
            *x = i as u8 + 1;
91
        }
92
        assert_eq!(
93
            &arr[..],
94
            [
95
                u32::from_ne_bytes([1u8, 2, 3, 4]),
96
                u32::from_ne_bytes([5u8, 6, 7, 8]),
97
            ]
98
        );
99
    }
100
101
    #[test]
102
    #[should_panic(expected = "Cannot convert 7 x u8 to f32")]
103
    fn panic_incompatible_size() {
104
        let slice = unsafe { std::slice::from_raw_parts_mut(4 as *mut u8, 7) };
105
        let _f32slice: &mut [f32] = slice.cast();
106
    }
107
108
    #[test]
109
    #[should_panic(expected = "Pointer 0x32 is misaligned for f32")]
110
    fn panic_incompatible_alignment() {
111
        let slice = unsafe { std::slice::from_raw_parts_mut(50 as *mut u8, 8) };
112
        let _f32slice: &mut [f32] = slice.cast();
113
    }
114
}