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

vigna / epserde-rs / 18937420329

30 Oct 2025 10:22AM UTC coverage: 53.501% (+9.2%) from 44.27%
18937420329

push

github

vigna
Added missing TypeHash impls for references to str and slices

0 of 5 new or added lines in 2 files covered. (0.0%)

787 of 1471 relevant lines covered (53.5%)

477.15 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 provide type hashes for `String` and `str` so that they can be used
19
//! in [`PhantomData`](core::marker::PhantomData).
20

21
use crate::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
// For use with PhantomData
37
impl TypeHash for String {
38
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
1✔
39
        "String".hash(hasher);
3✔
40
    }
41
}
42

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

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

52
impl DeserInner for String {
53
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
673✔
54
        let slice = unsafe { deser_full_vec_zero(backend) }?;
2,019✔
55
        Ok(String::from_utf8(slice).unwrap())
1,346✔
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
    #[inline(always)]
100
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
4✔
101
        Ok(unsafe { String::_deser_full_inner(backend) }?.into_boxed_str())
12✔
102
    }
103

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

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

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

121
// For use with PhantomData
122
impl TypeHash for &str {
NEW
123
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
×
NEW
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<()> {
325✔
136
        ser_slice_zero(backend, self.as_bytes())
975✔
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

© 2025 Coveralls, Inc