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

vigna / epserde-rs / 18041364878

26 Sep 2025 02:56PM UTC coverage: 43.537% (+1.7%) from 41.837%
18041364878

push

github

vigna
fmt

650 of 1493 relevant lines covered (43.54%)

271.38 hits per line

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

80.77
/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
    const ZERO_COPY_MISMATCH: bool = false;
47

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

53
impl DeserInner for String {
54
    unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
673✔
55
        let slice = unsafe { deser_full_vec_zero(backend) }?;
2,019✔
56
        Ok(String::from_utf8(slice).unwrap())
×
57
    }
58

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

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

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

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

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

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

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

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

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

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

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

123
impl SerInner for &str {
124
    type SerType = Box<str>;
125
    const IS_ZERO_COPY: bool = false;
126
    const ZERO_COPY_MISMATCH: bool = false;
127

128
    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
2✔
129
        ser_slice_zero(backend, self.as_bytes())
6✔
130
    }
131
}
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