1use core::fmt;
4#[cfg(feature = "std")]
5use std::io;
6
7use crate::prelude::*;
8
9#[cfg(feature = "serde")]
10pub trait WithOrWithoutSerde: Serialize + for<'de> Deserialize<'de> {}
11#[cfg(feature = "serde")]
12impl<T> WithOrWithoutSerde for T where T: Serialize + for<'de> Deserialize<'de> {}
13
14#[cfg(not(feature = "serde"))]
15pub trait WithOrWithoutSerde {}
16#[cfg(not(feature = "serde"))]
17impl<T> WithOrWithoutSerde for T {}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23pub struct Advance(usize);
24
25impl Advance {
26 #[inline]
28 #[must_use]
29 pub const fn new(n: usize) -> Self {
30 Self(n)
31 }
32}
33
34impl Op for Advance {
35 #[cfg(feature = "std")]
36 #[inline]
37 fn write_to_io(&self, stream: &mut dyn io::Write) -> Result<usize> {
38 Fill::new(self.0, 0).write_to_io(stream)
39 }
40
41 #[inline]
42 fn write_to(&self, out: impl AsMut<[u8]>) -> Result<usize> {
43 Fill::new(self.0, 0).write_to(out)
44 }
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50pub struct Fill(usize, u8);
51
52impl Fill {
53 #[inline]
55 #[must_use]
56 pub const fn new(len: usize, chr: u8) -> Self {
57 Self(len, chr)
58 }
59}
60
61impl Op for Fill {
62 #[cfg(feature = "std")]
63 #[inline]
64 fn write_to_io(&self, stream: &mut dyn io::Write) -> Result<usize> {
65 use core::slice;
66 let rchr = slice::from_ref(&self.1);
67 for _ in 0..self.0 {
68 stream.write_all(rchr)?;
69 }
70 Ok(self.0)
71 }
72
73 #[inline]
74 fn write_to(&self, mut out: impl AsMut<[u8]>) -> Result<usize> {
75 out.as_mut()
76 .get_mut(..self.0)
77 .ok_or_else(|| Error::buffer_too_small(self.0))?
78 .fill(self.1);
79 Ok(self.0)
80 }
81}
82
83pub trait EncodableInteger:
85 Copy + Clone + Sized + fmt::Debug + PartialEq + Eq + Send + Sync + WithOrWithoutSerde
86{
87 fn n(self) -> usize;
89
90 #[cfg(feature = "std")]
96 fn write_be_io(self, stream: &mut dyn io::Write) -> Result<()>;
97
98 #[cfg(feature = "std")]
104 fn write_le_io(self, stream: &mut dyn io::Write) -> Result<()>;
105
106 fn write_be(self, out: impl AsMut<[u8]>) -> Result<()>;
113
114 fn write_le(self, out: impl AsMut<[u8]>) -> Result<()>;
121}
122
123macro_rules! impl_encodable_integer_for {
125 ($i:ident) => {
126 impl EncodableInteger for $i {
127 #[inline]
128 #[must_use]
129 fn n(self) -> usize {
130 ($i::BITS >> 3).try_into().expect("unreachable")
131 }
132
133 #[cfg(feature = "std")]
134 #[inline]
135 fn write_be_io(self, stream: &mut dyn io::Write) -> Result<()> {
136 stream.write_all(&self.to_be_bytes()).map_err(Error::from)
137 }
138
139 #[cfg(feature = "std")]
140 #[inline]
141 fn write_le_io(self, stream: &mut dyn io::Write) -> Result<()> {
142 stream.write_all(&self.to_le_bytes()).map_err(Error::from)
143 }
144
145 #[inline]
146 fn write_be(self, mut out: impl AsMut<[u8]>) -> Result<()> {
147 let n = self.n();
148 let out = out
149 .as_mut()
150 .get_mut(..n)
151 .ok_or(Error::buffer_too_small(n))?;
152 unsafe {
156 out.as_mut_ptr().copy_from(self.to_be_bytes().as_ptr(), n);
157 }
158 Ok(())
159 }
160
161 #[inline]
162 fn write_le(self, mut out: impl AsMut<[u8]>) -> Result<()> {
163 let n = self.n();
164 let out = out
165 .as_mut()
166 .get_mut(..n)
167 .ok_or(Error::buffer_too_small(n))?;
168 unsafe {
172 out.as_mut_ptr().copy_from(self.to_le_bytes().as_ptr(), n);
173 }
174 Ok(())
175 }
176 }
177 };
178}
179
180impl_encodable_integer_for!(u8);
181impl_encodable_integer_for!(u16);
182impl_encodable_integer_for!(u32);
183impl_encodable_integer_for!(u64);
184
185#[derive(Clone, Copy, Debug, PartialEq, Eq)]
189#[non_exhaustive]
190pub enum WriteInteger<I>
191where
192 I: EncodableInteger + WithOrWithoutSerde,
193{
194 BigEndian(I),
196
197 LittleEndian(I),
199}
200
201impl<I> WriteInteger<I>
202where
203 I: EncodableInteger,
204{
205 #[inline]
207 #[must_use]
208 pub const fn new_be(value: I) -> Self {
209 Self::BigEndian(value)
210 }
211
212 #[inline]
214 #[must_use]
215 pub const fn new_le(value: I) -> Self {
216 Self::LittleEndian(value)
217 }
218}
219
220impl<I> Op for WriteInteger<I>
221where
222 I: EncodableInteger,
223{
224 #[cfg(feature = "std")]
225 #[inline]
226 fn write_to_io(&self, stream: &mut dyn io::Write) -> Result<usize> {
227 match self {
228 Self::BigEndian(n) => n.write_be_io(stream).map(|()| n.n()),
229 Self::LittleEndian(n) => n.write_le_io(stream).map(|()| n.n()),
230 }
231 }
232
233 #[inline]
234 fn write_to(&self, out: impl AsMut<[u8]>) -> Result<usize> {
235 match self {
236 Self::BigEndian(n) => n.write_be(out).map(|()| n.n()),
237 Self::LittleEndian(n) => n.write_le(out).map(|()| n.n()),
238 }
239 }
240}
241
242#[derive(Clone, Copy, Debug, PartialEq, Eq)]
245#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
246pub struct WriteBuffer<'buf>(&'buf [u8]);
247
248impl<'buf> WriteBuffer<'buf> {
249 #[inline]
251 #[must_use]
252 pub fn new(buffer: &'buf (impl AsRef<[u8]> + 'buf)) -> Self {
253 Self(buffer.as_ref())
254 }
255}
256
257impl Op for WriteBuffer<'_> {
258 #[cfg(feature = "std")]
259 #[inline]
260 fn write_to_io(&self, stream: &mut dyn io::Write) -> Result<usize> {
261 stream
262 .write_all(self.0)
263 .map(|()| self.0.len())
264 .map_err(Error::from)
265 }
266
267 #[inline]
268 fn write_to(&self, mut out: impl AsMut<[u8]>) -> Result<usize> {
269 let n = self.0.len();
270 let out_slice = out
271 .as_mut()
272 .get_mut(..n)
273 .ok_or_else(|| Error::buffer_too_small(n))?;
274 unsafe {
278 out_slice.as_mut_ptr().copy_from(self.0.as_ptr(), n);
279 }
280 Ok(n)
281 }
282}
283
284#[cfg(test)]
285mod tests {
286 mod advance {
287 use crate::ops::Advance;
288
289 use crate::prelude::*;
290
291 #[cfg(feature = "std")]
292 #[test]
293 fn test_io() -> Result<()> {
294 {
295 let mut stream = Vec::new();
296 let advance = Advance::new(0);
297 assert_eq!(advance.write_to_io(&mut stream).unwrap(), 0);
298 assert!(stream.is_empty());
299 }
300 {
301 let mut stream = Vec::new();
302 let advance = Advance::new(42);
303 assert_eq!(advance.write_to_io(&mut stream).unwrap(), 42);
304 assert_eq!(stream.len(), 42);
305 assert_eq!(
306 stream.as_slice(),
307 &[
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 ]
311 );
312 }
313 {
314 let mut stream = vec![42u8; 2];
315 let advance = Advance::new(42);
316 assert_eq!(advance.write_to_io(&mut stream).unwrap(), 42);
317 assert_eq!(stream.len(), 44);
318 assert_eq!(
319 stream.as_slice(),
320 &[
321 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
323 ]
324 );
325 }
326 Ok(())
327 }
328
329 #[cfg(feature = "std")]
330 #[test]
331 fn test() -> Result<()> {
332 {
333 let mut stream = vec![0u8; 10];
334 let advance = Advance::new(10);
335 assert_eq!(advance.write_to(&mut stream).unwrap(), 10);
336 assert_eq!(stream.len(), 10);
337 assert_eq!(stream.as_slice(), &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]);
338 }
339 {
340 let mut stream = vec![0u8; 9];
341 let advance = Advance::new(10);
342 let err = advance.write_to(&mut stream).unwrap_err();
343 let io_err = err.io().unwrap();
344 assert_eq!(io_err.kind(), std::io::ErrorKind::WriteZero);
345 assert_eq!(stream.len(), 9);
346 assert_eq!(stream.as_slice(), &[0, 0, 0, 0, 0, 0, 0, 0, 0,]);
347 }
348 Ok(())
349 }
350 }
351
352 mod fill {
353 use crate::ops::Fill;
354
355 use crate::prelude::*;
356
357 #[cfg(feature = "std")]
358 #[test]
359 fn test_io() -> Result<()> {
360 {
361 let mut stream = Vec::new();
362 let fill = Fill::new(0, 0x41);
363 assert_eq!(fill.write_to_io(&mut stream).unwrap(), 0);
364 assert_eq!(stream.len(), 0);
365 }
366 {
367 let mut stream = Vec::new();
368 let fill = Fill::new(42, 0x41);
369 assert_eq!(fill.write_to_io(&mut stream).unwrap(), 42);
370 assert_eq!(stream.len(), 42);
371 assert_eq!(
372 String::from_utf8(stream).as_deref(),
373 Ok("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
374 );
375 }
376 {
377 let mut stream = vec![0x42u8; 4];
378 let fill = Fill::new(42, 0x41);
379 assert_eq!(fill.write_to_io(&mut stream).unwrap(), 42);
380 assert_eq!(stream.len(), 46);
381 assert_eq!(
382 String::from_utf8(stream).as_deref(),
383 Ok("BBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
384 );
385 }
386 Ok(())
387 }
388
389 #[cfg(feature = "std")]
390 #[test]
391 fn test() -> Result<()> {
392 {
393 let mut stream = vec![0u8; 10];
394 let fill = Fill::new(10, 0x41);
395 assert_eq!(fill.write_to(&mut stream).unwrap(), 10);
396 assert_eq!(stream.len(), 10);
397 assert_eq!(String::from_utf8(stream).as_deref(), Ok("AAAAAAAAAA"));
398 }
399
400 {
401 let mut stream = vec![0u8; 9];
402 let fill = Fill::new(10, 0x41);
403 let err = fill.write_to(&mut stream).unwrap_err();
404 let io_err = err.io().unwrap();
405 assert_eq!(io_err.kind(), std::io::ErrorKind::WriteZero);
406 assert_eq!(stream.len(), 9);
407 assert_eq!(
408 stream.as_slice(),
409 &[0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,]
410 );
411 }
412 Ok(())
413 }
414 }
415
416 mod integers {
417 use crate::ops::{EncodableInteger, WriteInteger};
418
419 use crate::prelude::*;
420
421 #[test]
422 fn test_constructors() -> Result<()> {
423 assert_eq!(WriteInteger::new_be(1u8), WriteInteger::BigEndian(1u8));
424 assert_eq!(<_ as EncodableInteger>::n(1u8), 1);
425 assert_eq!(WriteInteger::new_le(1u8), WriteInteger::LittleEndian(1u8));
426 assert_eq!(WriteInteger::new_be(1u16), WriteInteger::BigEndian(1u16));
427 assert_eq!(<_ as EncodableInteger>::n(1u16), 2);
428 assert_eq!(WriteInteger::new_le(1u16), WriteInteger::LittleEndian(1u16));
429 assert_eq!(WriteInteger::new_be(1u32), WriteInteger::BigEndian(1u32));
430 assert_eq!(<_ as EncodableInteger>::n(1u32), 4);
431 assert_eq!(WriteInteger::new_le(1u32), WriteInteger::LittleEndian(1u32));
432 assert_eq!(WriteInteger::new_be(1u64), WriteInteger::BigEndian(1u64));
433 assert_eq!(<_ as EncodableInteger>::n(1u64), 8);
434 assert_eq!(WriteInteger::new_le(1u64), WriteInteger::LittleEndian(1u64));
435 Ok(())
436 }
437
438 #[cfg(feature = "std")]
439 #[test]
440 fn test_encodable_integer_io() -> Result<()> {
441 {
442 let mut stream = Vec::new();
443 assert_eq!(
444 WriteInteger::new_be(1u8).write_to_io(&mut stream).unwrap(),
445 1
446 );
447 assert_eq!(stream.len(), 1);
448 assert_eq!(
449 WriteInteger::new_le(2u8).write_to_io(&mut stream).unwrap(),
450 1
451 );
452 assert_eq!(stream.len(), 2);
453 assert_eq!(stream.as_slice(), &[1, 2]);
454 }
455
456 {
457 let mut stream = vec![2u8; 1];
458 assert_eq!(
459 WriteInteger::new_be(1u8).write_to_io(&mut stream).unwrap(),
460 1
461 );
462 assert_eq!(stream.len(), 2);
463 assert_eq!(stream.as_slice(), &[2u8, 1u8]);
464 }
465
466 {
467 let mut stream = Vec::new();
468 assert_eq!(
469 WriteInteger::new_be(0xdeadu16)
470 .write_to_io(&mut stream)
471 .unwrap(),
472 2
473 );
474 assert_eq!(stream.len(), 2);
475 assert_eq!(stream.as_slice(), &[0xde, 0xad]);
476 }
477
478 {
479 let mut stream = Vec::new();
480 assert_eq!(
481 WriteInteger::new_le(0xdeadu16)
482 .write_to_io(&mut stream)
483 .unwrap(),
484 2
485 );
486 assert_eq!(stream.len(), 2);
487 assert_eq!(stream.as_slice(), &[0xad, 0xde]);
488 }
489
490 {
491 let mut stream = Vec::new();
492 assert_eq!(
493 WriteInteger::new_be(0xdeadbeefu32)
494 .write_to_io(&mut stream)
495 .unwrap(),
496 4
497 );
498 assert_eq!(stream.len(), 4);
499 assert_eq!(stream.as_slice(), &[0xde, 0xad, 0xbe, 0xef]);
500 }
501
502 {
503 let mut stream = Vec::new();
504 assert_eq!(
505 WriteInteger::new_le(0xdeadbeefu32)
506 .write_to_io(&mut stream)
507 .unwrap(),
508 4
509 );
510 assert_eq!(stream.len(), 4);
511 assert_eq!(stream.as_slice(), &[0xef, 0xbe, 0xad, 0xde]);
512 }
513
514 {
515 let mut stream = Vec::new();
516 assert_eq!(
517 WriteInteger::new_be(0xdeadbeefcafebabeu64)
518 .write_to_io(&mut stream)
519 .unwrap(),
520 8
521 );
522 assert_eq!(stream.len(), 8);
523 assert_eq!(
524 stream.as_slice(),
525 &[0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe]
526 );
527 }
528
529 {
530 let mut stream = Vec::new();
531 assert_eq!(
532 WriteInteger::new_le(0xdeadbeefcafebabeu64)
533 .write_to_io(&mut stream)
534 .unwrap(),
535 8
536 );
537 assert_eq!(stream.len(), 8);
538 assert_eq!(
539 stream.as_slice(),
540 &[0xbe, 0xba, 0xfe, 0xca, 0xef, 0xbe, 0xad, 0xde]
541 );
542 }
543 Ok(())
544 }
545 }
546}