• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / epserde-rs / 18002014973

25 Sep 2025 08:44AM UTC coverage: 42.365% (-0.3%) from 42.636%
18002014973

push

github

vigna
DeserType everywhere

3 of 5 new or added lines in 3 files covered. (60.0%)

225 existing lines in 7 files now uncovered.

627 of 1480 relevant lines covered (42.36%)

240.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.36
/epserde/src/impls/array.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Inria
3
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
4
 *
5
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
6
 */
7

8
//! Implementations for arrays.
9

10
use crate::prelude::*;
11
use core::hash::Hash;
12
use core::mem::MaybeUninit;
13
use deser::*;
14
use ser::*;
15

16
unsafe impl<T: CopyType, const N: usize> CopyType for [T; N] {
17
    type Copy = T::Copy;
18
}
19

20
impl<T: TypeHash, const N: usize> TypeHash for [T; N] {
21
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
67✔
22
        "[]".hash(hasher);
201✔
23
        hasher.write_usize(N);
134✔
24
        T::type_hash(hasher);
134✔
25
    }
26
}
27

28
impl<T: AlignHash, const N: usize> AlignHash for [T; N] {
29
    fn align_hash(hasher: &mut impl core::hash::Hasher, offset_of: &mut usize) {
62✔
30
        if N == 0 {
62✔
31
            return;
×
32
        }
33
        T::align_hash(hasher, offset_of);
×
34
        *offset_of += (N - 1) * size_of::<T>();
×
35
    }
36
}
37

38
impl<T: MaxSizeOf, const N: usize> MaxSizeOf for [T; N] {
39
    fn max_size_of() -> usize {
43✔
40
        T::max_size_of()
43✔
41
    }
42
}
43

44
impl<T: CopyType + SerInner + TypeHash + AlignHash, const N: usize> SerInner for [T; N]
45
where
46
    [T; N]: SerHelper<<T as CopyType>::Copy>,
47
{
48
    type SerType = Self;
49
    const IS_ZERO_COPY: bool = T::IS_ZERO_COPY;
50
    const ZERO_COPY_MISMATCH: bool = T::ZERO_COPY_MISMATCH;
51
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
22✔
52
        unsafe { SerHelper::_ser_inner(self, backend) }
66✔
53
    }
54
}
55

56
impl<T: ZeroCopy + SerInner + TypeHash + AlignHash, const N: usize> SerHelper<Zero> for [T; N] {
57
    #[inline(always)]
58
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
14✔
59
        ser_zero(backend, self)
42✔
60
    }
61
}
62

63
impl<T: DeepCopy + SerInner, const N: usize> SerHelper<Deep> for [T; N] {
64
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
8✔
65
        for item in self.iter() {
32✔
66
            backend.write("item", item)?;
64✔
67
        }
68
        Ok(())
8✔
69
    }
70
}
71

72
impl<T: CopyType + DeserInner, const N: usize> DeserInner for [T; N]
73
where
74
    [T; N]: DeserHelper<<T as CopyType>::Copy, FullType = [T; N]>,
75
{
76
    type DeserType<'a> = <[T; N] as DeserHelper<<T as CopyType>::Copy>>::DeserType<'a>;
77

78
    #[inline(always)]
79
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
21✔
80
        unsafe { <[T; N] as DeserHelper<<T as CopyType>::Copy>>::_deser_full_inner_impl(backend) }
42✔
81
    }
82

83
    #[inline(always)]
84
    unsafe fn _deser_eps_inner<'a>(
13✔
85
        backend: &mut SliceWithPos<'a>,
86
    ) -> deser::Result<<[T; N] as DeserHelper<<T as CopyType>::Copy>>::DeserType<'a>> {
87
        unsafe { <[T; N] as DeserHelper<<T as CopyType>::Copy>>::_deser_eps_inner_impl(backend) }
26✔
88
    }
89
}
90

91
impl<T: ZeroCopy + DeserInner, const N: usize> DeserHelper<Zero> for [T; N] {
92
    type FullType = Self;
93
    type DeserType<'a> = &'a [T; N];
94

95
    unsafe fn _deser_full_inner_impl(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
17✔
96
        let mut res = MaybeUninit::<[T; N]>::uninit();
34✔
97
        backend.align::<T>()?;
34✔
98
        // SAFETY: read_exact guarantees that the array will be filled with data.
99
        unsafe {
100
            backend.read_exact(res.assume_init_mut().align_to_mut::<u8>().1)?;
17✔
101
            Ok(res.assume_init())
17✔
102
        }
103
    }
104

105
    unsafe fn _deser_eps_inner_impl<'a>(
9✔
106
        backend: &mut SliceWithPos<'a>,
107
    ) -> deser::Result<DeserType<'a, Self>> {
108
        backend.align::<T>()?;
18✔
109
        let bytes = std::mem::size_of::<[T; N]>();
9✔
UNCOV
110
        let (pre, data, after) = unsafe { backend.data[..bytes].align_to::<[T; N]>() };
×
UNCOV
111
        debug_assert!(pre.is_empty());
×
112
        debug_assert!(after.is_empty());
27✔
113
        let res = &data[0];
18✔
114
        backend.skip(bytes);
27✔
115
        Ok(res)
9✔
116
    }
117
}
118

119
impl<T: DeepCopy + DeserInner, const N: usize> DeserHelper<Deep> for [T; N] {
120
    type FullType = Self;
121
    type DeserType<'a> = [DeserType<'a, T>; N];
122

123
    unsafe fn _deser_full_inner_impl(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
8✔
124
        let mut res = MaybeUninit::<[T; N]>::uninit();
16✔
125
        for item in &mut unsafe { res.assume_init_mut().iter_mut() } {
32✔
126
            unsafe { std::ptr::write(item, T::_deser_full_inner(backend)?) };
64✔
127
        }
128
        Ok(unsafe { res.assume_init() })
8✔
129
    }
130

131
    unsafe fn _deser_eps_inner_impl<'a>(
8✔
132
        backend: &mut SliceWithPos<'a>,
133
    ) -> deser::Result<DeserType<'a, Self>> {
134
        let mut res = MaybeUninit::<DeserType<'a, Self>>::uninit();
16✔
135
        for item in &mut unsafe { res.assume_init_mut().iter_mut() } {
32✔
136
            unsafe { std::ptr::write(item, T::_deser_eps_inner(backend)?) };
64✔
137
        }
138
        Ok(unsafe { res.assume_init() })
8✔
139
    }
140
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc