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

vigna / epserde-rs / 28525681214

01 Jul 2026 02:39PM UTC coverage: 44.084% (+0.1%) from 43.952%
28525681214

push

github

vigna
Removed MIGHT_BE_ZERO_COPY, as IS_ZERO_COPY subsumes it (final part)

883 of 2003 relevant lines covered (44.08%)

449.05 hits per line

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

92.86
/epserde/src/impls/string.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 strings.
9
//!
10
//! All string types have the same serialization type, `Box<str>`, and the same
11
//! deserialization type, `&str`. Thus, you can serialize a `String` and fully
12
//! deserialize it as `Box<str>`.
13
//!
14
//! Similarly to the case of [slices](crate::impls::slice), there is
15
//! a convenience [`SerInner`] implementation for `&str` that
16
//! serializes it as `Box<str>`.
17
//!
18
//! We implement [`TypeHash`] for `str` so that it can be used in
19
//! [`PhantomData`](core::marker::PhantomData).
20

21
use crate::{check_covariance, prelude::*};
22
use core::hash::Hash;
23
use deser::*;
24
use ser::*;
25

26
#[cfg(not(feature = "std"))]
27
use alloc::boxed::Box;
28

29
unsafe impl CopyType for String {
30
    type Copy = Deep;
31
}
32

33
#[cfg(not(feature = "std"))]
34
use alloc::string::String;
35

36
impl TypeHash for String {
37
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
1✔
38
        "String".hash(hasher);
3✔
39
    }
40
}
41

42
impl SerInner for String {
43
    type SerType = Box<str>;
44
    const IS_ZERO_COPY: bool = false;
45

46
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
22✔
47
        ser_slice_zero(backend, self.as_bytes())
66✔
48
    }
49
}
50

51
impl DeserInner for String {
52
    check_covariance!();
53
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
900✔
54
        let slice = unsafe { deser_full_vec_zero(backend) }?;
2,700✔
55
        String::from_utf8(slice).map_err(|_| deser::Error::InvalidData)
2,478✔
56
    }
57

58
    type DeserType<'a> = &'a str;
59

60
    unsafe fn _deser_eps_inner<'a>(
32✔
61
        backend: &mut SliceWithPos<'a>,
62
    ) -> deser::Result<Self::DeserType<'a>> {
63
        let slice = unsafe { deser_eps_slice_zero(backend) }?;
96✔
64
        // SAFETY: Actually this is unsafe if the data we read is not valid UTF-8
65
        Ok({
32✔
66
            unsafe {
32✔
67
                #[allow(clippy::transmute_bytes_to_str)]
32✔
68
                core::mem::transmute::<&'_ [u8], &'_ str>(slice)
32✔
69
            }
70
        })
71
    }
72
}
73

74
unsafe impl CopyType for Box<str> {
75
    type Copy = Deep;
76
}
77

78
impl TypeHash for Box<str> {
79
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
41✔
80
        "Box<str>".hash(hasher);
123✔
81
    }
82
}
83

84
impl AlignHash for Box<str> {
85
    fn align_hash(_hasher: &mut impl core::hash::Hasher, _offset_of: &mut usize) {}
88✔
86
}
87

88
impl SerInner for Box<str> {
89
    type SerType = Self;
90
    // Box<[$ty]> can, but Vec<Box<[$ty]>> cannot!
91
    const IS_ZERO_COPY: bool = false;
92

93
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
2✔
94
        ser_slice_zero(backend, self.as_bytes())
6✔
95
    }
96
}
97

98
impl DeserInner for Box<str> {
99
    check_covariance!();
100
    #[inline(always)]
101
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
4✔
102
        Ok(unsafe { String::_deser_full_inner(backend) }?.into_boxed_str())
12✔
103
    }
104

105
    type DeserType<'a> = &'a str;
106

107
    #[inline(always)]
108
    unsafe fn _deser_eps_inner<'a>(
6✔
109
        backend: &mut SliceWithPos<'a>,
110
    ) -> deser::Result<Self::DeserType<'a>> {
111
        unsafe { String::_deser_eps_inner(backend) }
12✔
112
    }
113
}
114

115
// For use with PhantomData
116
impl TypeHash for str {
117
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
4✔
118
        "str".hash(hasher);
12✔
119
    }
120
}
121

122
impl TypeHash for &str {
123
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
×
124
        "&str".hash(hasher);
×
125
    }
126
}
127
unsafe impl CopyType for &str {
128
    type Copy = Deep;
129
}
130

131
impl SerInner for &str {
132
    type SerType = Box<str>;
133
    const IS_ZERO_COPY: bool = false;
134

135
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
431✔
136
        ser_slice_zero(backend, self.as_bytes())
1,293✔
137
    }
138
}
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