Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/revision-0.10.0/src/implementations/string.rs
Line
Count
Source (jump to first uncovered line)
1
use core::str;
2
3
use crate::{Error, Revisioned};
4
5
use super::vecs::serialize_slice;
6
7
impl Revisioned for String {
8
0
  fn revision() -> u16 {
9
0
    1
10
0
  }
11
12
  #[inline]
13
0
  fn serialize_revisioned<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
14
0
    serialize_slice(self.as_bytes(), writer)
15
0
  }
16
17
  #[inline]
18
0
  fn deserialize_revisioned<R: std::io::Read>(reader: &mut R) -> Result<Self, Error> {
19
0
    let bytes = Vec::<u8>::deserialize_revisioned(reader)?;
20
0
    String::from_utf8(bytes).map_err(|x| Error::Utf8Error(x.utf8_error()))
Unexecuted instantiation: <alloc::string::String as revision::Revisioned>::deserialize_revisioned::<&[u8]>::{closure#0}
Unexecuted instantiation: <alloc::string::String as revision::Revisioned>::deserialize_revisioned::<_>::{closure#0}
21
0
  }
Unexecuted instantiation: <alloc::string::String as revision::Revisioned>::deserialize_revisioned::<&[u8]>
Unexecuted instantiation: <alloc::string::String as revision::Revisioned>::deserialize_revisioned::<_>
22
}
23
24
impl Revisioned for char {
25
0
  fn revision() -> u16 {
26
0
    1
27
0
  }
28
29
0
  fn serialize_revisioned<W: std::io::Write>(&self, w: &mut W) -> Result<(), Error> {
30
0
    let buffer = &mut [0u8; 4];
31
0
    w.write_all(self.encode_utf8(buffer).as_bytes()).map_err(Error::Io)
32
0
  }
33
34
0
  fn deserialize_revisioned<R: std::io::Read>(r: &mut R) -> Result<Self, Error>
35
0
  where
36
0
    Self: Sized,
37
0
  {
38
0
    let mut buffer = [0u8; 4];
39
0
    r.read_exact(&mut buffer[..1]).map_err(Error::Io)?;
40
41
0
    let len = CHAR_LENGTH[buffer[0] as usize];
42
0
43
0
    if len == 0 {
44
0
      return Err(Error::InvalidCharEncoding);
45
0
    }
46
0
47
0
    r.read_exact(&mut buffer[1..(len as usize)]).map_err(Error::Io)?;
48
49
0
    str::from_utf8(&buffer[..(len as usize)])
50
0
      .map_err(|_| Error::InvalidCharEncoding)
51
0
      .map(|x| x.chars().next().unwrap())
52
0
  }
53
}
54
55
static CHAR_LENGTH: [u8; 256] = const {
56
  let mut r = [0u8; 256];
57
  let mut i = 0;
58
  while i < 256 {
59
    if i & 0b1000_0000 == 0 {
60
      r[i] = 1;
61
    } else if i & 0b1110_0000 == 0b1100_0000 {
62
      r[i] = 2;
63
    } else if i & 0b1111_0000 == 0b1110_0000 {
64
      r[i] = 3;
65
    } else if i & 0b1111_1000 == 0b1111_0000 {
66
      r[i] = 4;
67
    }
68
69
    i += 1;
70
  }
71
72
  r
73
};
74
75
#[cfg(test)]
76
mod tests {
77
78
  use std::char;
79
80
  use crate::implementations::assert_bincode_compat;
81
82
  use super::Revisioned;
83
84
  #[test]
85
  fn test_string() {
86
    let val = String::from("this is a test");
87
    let mut mem: Vec<u8> = vec![];
88
    val.serialize_revisioned(&mut mem).unwrap();
89
    assert_eq!(mem.len(), 15);
90
    let out = <String as Revisioned>::deserialize_revisioned(&mut mem.as_slice()).unwrap();
91
    assert_eq!(val, out);
92
  }
93
94
  #[test]
95
  fn test_char() {
96
    let char = '𐃌';
97
    let mut mem = Vec::new();
98
    char.serialize_revisioned(&mut mem).unwrap();
99
    let out = Revisioned::deserialize_revisioned(&mut mem.as_slice()).unwrap();
100
    assert_eq!(char, out);
101
  }
102
103
  #[test]
104
  fn bincode_compat_char() {
105
    assert_bincode_compat(&char::MAX);
106
    assert_bincode_compat(&'\0');
107
    assert_bincode_compat(&'z');
108
    assert_bincode_compat(&'0');
109
    // in the 0x7F - 0x07FF range
110
    assert_bincode_compat(&'ʘ');
111
    // in the 0x7FF - 0xFFFF range
112
    assert_bincode_compat(&'ꚸ');
113
    // in the 0xFFFF - 0x10FFFF range
114
    assert_bincode_compat(&'𐃌');
115
  }
116
117
  #[test]
118
  fn bincode_compat_string() {
119
    assert_bincode_compat(&char::MAX.to_string());
120
    assert_bincode_compat(&'\0'.to_string());
121
    assert_bincode_compat(&'z'.to_string());
122
    assert_bincode_compat(&'0'.to_string());
123
    // in the 0x7F - 0x07FF range
124
    assert_bincode_compat(&'ʘ'.to_string());
125
    // in the 0x7FF - 0xFFFF range
126
    assert_bincode_compat(&'ꚸ'.to_string());
127
    // in the 0xFFFF - 0x10FFFF range
128
    assert_bincode_compat(&'𐃌'.to_string());
129
  }
130
}