1 | #![warn (rust_2018_idioms)] |
2 | |
3 | use bytes::buf::UninitSlice; |
4 | use bytes::{BufMut, BytesMut}; |
5 | use core::fmt::Write; |
6 | use core::mem::MaybeUninit; |
7 | use core::usize; |
8 | |
9 | #[test] |
10 | fn test_vec_as_mut_buf() { |
11 | let mut buf = Vec::with_capacity(64); |
12 | |
13 | assert_eq!(buf.remaining_mut(), isize::MAX as usize); |
14 | |
15 | assert!(buf.chunk_mut().len() >= 64); |
16 | |
17 | buf.put(&b"zomg" [..]); |
18 | |
19 | assert_eq!(&buf, b"zomg" ); |
20 | |
21 | assert_eq!(buf.remaining_mut(), isize::MAX as usize - 4); |
22 | assert_eq!(buf.capacity(), 64); |
23 | |
24 | for _ in 0..16 { |
25 | buf.put(&b"zomg" [..]); |
26 | } |
27 | |
28 | assert_eq!(buf.len(), 68); |
29 | } |
30 | |
31 | #[test] |
32 | fn test_vec_put_bytes() { |
33 | let mut buf = Vec::new(); |
34 | buf.push(17); |
35 | buf.put_bytes(19, 2); |
36 | assert_eq!([17, 19, 19], &buf[..]); |
37 | } |
38 | |
39 | #[test] |
40 | fn test_put_u8() { |
41 | let mut buf = Vec::with_capacity(8); |
42 | buf.put_u8(33); |
43 | assert_eq!(b" \x21" , &buf[..]); |
44 | } |
45 | |
46 | #[test] |
47 | fn test_put_u16() { |
48 | let mut buf = Vec::with_capacity(8); |
49 | buf.put_u16(8532); |
50 | assert_eq!(b" \x21\x54" , &buf[..]); |
51 | |
52 | buf.clear(); |
53 | buf.put_u16_le(8532); |
54 | assert_eq!(b" \x54\x21" , &buf[..]); |
55 | } |
56 | |
57 | #[test] |
58 | fn test_put_int() { |
59 | let mut buf = Vec::with_capacity(8); |
60 | buf.put_int(0x1020304050607080, 3); |
61 | assert_eq!(b" \x60\x70\x80" , &buf[..]); |
62 | } |
63 | |
64 | #[test] |
65 | #[should_panic ] |
66 | fn test_put_int_nbytes_overflow() { |
67 | let mut buf = Vec::with_capacity(8); |
68 | buf.put_int(0x1020304050607080, 9); |
69 | } |
70 | |
71 | #[test] |
72 | fn test_put_int_le() { |
73 | let mut buf = Vec::with_capacity(8); |
74 | buf.put_int_le(0x1020304050607080, 3); |
75 | assert_eq!(b" \x80\x70\x60" , &buf[..]); |
76 | } |
77 | |
78 | #[test] |
79 | #[should_panic ] |
80 | fn test_put_int_le_nbytes_overflow() { |
81 | let mut buf = Vec::with_capacity(8); |
82 | buf.put_int_le(0x1020304050607080, 9); |
83 | } |
84 | |
85 | #[test] |
86 | #[should_panic (expected = "cannot advance" )] |
87 | fn test_vec_advance_mut() { |
88 | // Verify fix for #354 |
89 | let mut buf = Vec::with_capacity(8); |
90 | unsafe { |
91 | buf.advance_mut(12); |
92 | } |
93 | } |
94 | |
95 | #[test] |
96 | fn test_clone() { |
97 | let mut buf = BytesMut::with_capacity(100); |
98 | buf.write_str("this is a test" ).unwrap(); |
99 | let buf2 = buf.clone(); |
100 | |
101 | buf.write_str(" of our emergency broadcast system" ).unwrap(); |
102 | assert!(buf != buf2); |
103 | } |
104 | |
105 | fn do_test_slice_small<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T) |
106 | where |
107 | for<'r> &'r mut T: BufMut, |
108 | { |
109 | let mut buf = [b'X' ; 8]; |
110 | |
111 | let mut slice = make(&mut buf[..]); |
112 | slice.put_bytes(b'A' , 2); |
113 | slice.put_u8(b'B' ); |
114 | slice.put_slice(b"BCC" ); |
115 | assert_eq!(2, slice.remaining_mut()); |
116 | assert_eq!(b"AABBCCXX" , &buf[..]); |
117 | |
118 | let mut slice = make(&mut buf[..]); |
119 | slice.put_u32(0x61626364); |
120 | assert_eq!(4, slice.remaining_mut()); |
121 | assert_eq!(b"abcdCCXX" , &buf[..]); |
122 | |
123 | let mut slice = make(&mut buf[..]); |
124 | slice.put_u32_le(0x30313233); |
125 | assert_eq!(4, slice.remaining_mut()); |
126 | assert_eq!(b"3210CCXX" , &buf[..]); |
127 | } |
128 | |
129 | fn do_test_slice_large<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T) |
130 | where |
131 | for<'r> &'r mut T: BufMut, |
132 | { |
133 | const LEN: usize = 100; |
134 | const FILL: [u8; LEN] = [b'Y' ; LEN]; |
135 | |
136 | let test = |fill: &dyn Fn(&mut &mut T, usize)| { |
137 | for buf_len in 0..LEN { |
138 | let mut buf = [b'X' ; LEN]; |
139 | for fill_len in 0..=buf_len { |
140 | let mut slice = make(&mut buf[..buf_len]); |
141 | fill(&mut slice, fill_len); |
142 | assert_eq!(buf_len - fill_len, slice.remaining_mut()); |
143 | let (head, tail) = buf.split_at(fill_len); |
144 | assert_eq!(&FILL[..fill_len], head); |
145 | assert!(tail.iter().all(|b| *b == b'X' )); |
146 | } |
147 | } |
148 | }; |
149 | |
150 | test(&|slice, fill_len| slice.put_slice(&FILL[..fill_len])); |
151 | test(&|slice, fill_len| slice.put_bytes(FILL[0], fill_len)); |
152 | } |
153 | |
154 | fn do_test_slice_put_slice_panics<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T) |
155 | where |
156 | for<'r> &'r mut T: BufMut, |
157 | { |
158 | let mut buf = [b'X' ; 4]; |
159 | let mut slice = make(&mut buf[..]); |
160 | slice.put_slice(b"12345" ); |
161 | } |
162 | |
163 | fn do_test_slice_put_bytes_panics<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T) |
164 | where |
165 | for<'r> &'r mut T: BufMut, |
166 | { |
167 | let mut buf = [b'X' ; 4]; |
168 | let mut slice = make(&mut buf[..]); |
169 | slice.put_bytes(b'1' , 5); |
170 | } |
171 | |
172 | #[test] |
173 | fn test_slice_buf_mut_small() { |
174 | do_test_slice_small(|x| x); |
175 | } |
176 | |
177 | #[test] |
178 | fn test_slice_buf_mut_large() { |
179 | do_test_slice_large(|x| x); |
180 | } |
181 | |
182 | #[test] |
183 | #[should_panic ] |
184 | fn test_slice_buf_mut_put_slice_overflow() { |
185 | do_test_slice_put_slice_panics(|x| x); |
186 | } |
187 | |
188 | #[test] |
189 | #[should_panic ] |
190 | fn test_slice_buf_mut_put_bytes_overflow() { |
191 | do_test_slice_put_bytes_panics(|x| x); |
192 | } |
193 | |
194 | fn make_maybe_uninit_slice(slice: &mut [u8]) -> &mut [MaybeUninit<u8>] { |
195 | // SAFETY: [u8] has the same layout as [MaybeUninit<u8>]. |
196 | unsafe { core::mem::transmute(slice) } |
197 | } |
198 | |
199 | #[test] |
200 | fn test_maybe_uninit_buf_mut_small() { |
201 | do_test_slice_small(make_maybe_uninit_slice); |
202 | } |
203 | |
204 | #[test] |
205 | fn test_maybe_uninit_buf_mut_large() { |
206 | do_test_slice_large(make_maybe_uninit_slice); |
207 | } |
208 | |
209 | #[test] |
210 | #[should_panic ] |
211 | fn test_maybe_uninit_buf_mut_put_slice_overflow() { |
212 | do_test_slice_put_slice_panics(make_maybe_uninit_slice); |
213 | } |
214 | |
215 | #[test] |
216 | #[should_panic ] |
217 | fn test_maybe_uninit_buf_mut_put_bytes_overflow() { |
218 | do_test_slice_put_bytes_panics(make_maybe_uninit_slice); |
219 | } |
220 | |
221 | #[allow (unused_allocation)] // This is intentional. |
222 | #[test] |
223 | fn test_deref_bufmut_forwards() { |
224 | struct Special; |
225 | |
226 | unsafe impl BufMut for Special { |
227 | fn remaining_mut(&self) -> usize { |
228 | unreachable!("remaining_mut" ); |
229 | } |
230 | |
231 | fn chunk_mut(&mut self) -> &mut UninitSlice { |
232 | unreachable!("chunk_mut" ); |
233 | } |
234 | |
235 | unsafe fn advance_mut(&mut self, _: usize) { |
236 | unreachable!("advance" ); |
237 | } |
238 | |
239 | fn put_u8(&mut self, _: u8) { |
240 | // specialized! |
241 | } |
242 | } |
243 | |
244 | // these should all use the specialized method |
245 | Special.put_u8(b'x' ); |
246 | (&mut Special as &mut dyn BufMut).put_u8(b'x' ); |
247 | (Box::new(Special) as Box<dyn BufMut>).put_u8(b'x' ); |
248 | Box::new(Special).put_u8(b'x' ); |
249 | } |
250 | |
251 | #[test] |
252 | #[should_panic ] |
253 | fn write_byte_panics_if_out_of_bounds() { |
254 | let mut data = [b'b' , b'a' , b'r' ]; |
255 | |
256 | let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) }; |
257 | slice.write_byte(4, b'f' ); |
258 | } |
259 | |
260 | #[test] |
261 | #[should_panic ] |
262 | fn copy_from_slice_panics_if_different_length_1() { |
263 | let mut data = [b'b' , b'a' , b'r' ]; |
264 | |
265 | let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) }; |
266 | slice.copy_from_slice(b"a" ); |
267 | } |
268 | |
269 | #[test] |
270 | #[should_panic ] |
271 | fn copy_from_slice_panics_if_different_length_2() { |
272 | let mut data = [b'b' , b'a' , b'r' ]; |
273 | |
274 | let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) }; |
275 | slice.copy_from_slice(b"abcd" ); |
276 | } |
277 | |