/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 | | } |