1#![no_std]
95#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
96#![deny(missing_docs)]
97
98use core::{fmt, marker::PhantomData, mem};
99
100#[cfg(feature = "std")]
101extern crate std;
102
103#[cfg(feature = "alloc")]
104extern crate alloc;
105
106#[cfg(feature = "std")]
107use std::{error, io, vec::Vec};
108
109#[cfg(feature = "alloc")]
110use alloc::vec::Vec;
111
112pub mod prelude {
113 pub use crate::{ReadBytes, ReadBytesExt, WriteBytes, WriteBytesExt};
123}
124
125pub type Result<T> = ::core::result::Result<T, Error>;
164
165#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
179pub enum Error {
180 EndOfStream,
195 #[doc(hidden)]
196 #[allow(non_camel_case_types)]
197 _nonexhaustive(()),
198}
199
200impl fmt::Display for Error {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 match *self {
203 Error::EndOfStream => f.write_str("unexpected end of stream"),
204 _ => unreachable!(),
205 }
206 }
207}
208
209#[cfg(feature = "std")]
210impl error::Error for Error {}
211
212#[cfg(feature = "std")]
213impl From<Error> for io::Error {
214 fn from(error: Error) -> Self {
215 match error {
216 Error::EndOfStream => io::ErrorKind::UnexpectedEof.into(),
217 _ => unreachable!(),
218 }
219 }
220}
221
222pub trait ReadBytes<'a>: AsRef<[u8]> {
301 fn read_exact(&mut self, n: usize) -> &'a [u8];
307
308 fn try_read_exact(&mut self, n: usize) -> crate::Result<&'a [u8]> {
313 if n > self.as_ref().len() {
314 Err(Error::EndOfStream)
315 } else {
316 Ok(self.read_exact(n))
317 }
318 }
319}
320
321impl<'a> ReadBytes<'a> for &'a [u8] {
322 fn read_exact(&mut self, n: usize) -> &'a [u8] {
323 let (a, b) = self.split_at(n);
324 *self = b;
325 a
326 }
327}
328
329impl<'a> ReadBytes<'a> for &'a mut [u8] {
330 fn read_exact(&mut self, n: usize) -> &'a [u8] {
331 let (a, b) = mem::replace(self, &mut []).split_at_mut(n);
332 *self = b;
333 a
334 }
335}
336
337impl<'a, R: ReadBytes<'a>> ReadBytes<'a> for &'_ mut R {
338 fn read_exact(&mut self, n: usize) -> &'a [u8] {
339 (**self).read_exact(n)
340 }
341
342 fn try_read_exact(&mut self, n: usize) -> crate::Result<&'a [u8]> {
343 (**self).try_read_exact(n)
344 }
345}
346
347macro_rules! impl_read {
354 ($doc:literal, $ty:ty, $fn:ident, $from_bytes:ident $( , )?) => {
355 #[doc = $doc]
356 #[inline]
357 fn $fn(&mut self) -> $ty {
358 <$ty>::$from_bytes(unsafe {
359 *(self.read_exact(mem::size_of::<$ty>()).as_ptr()
360 as *const [u8; mem::size_of::<$ty>()])
361 })
362 }
363 }
364}
365
366macro_rules! impl_try_read {
367 ($doc:literal, $ty:ty, $fn:ident, $from_bytes:ident $( , )?) => {
368 #[doc = $doc]
369 #[inline]
370 fn $fn(&mut self) -> crate::Result<$ty> {
371 Ok(<$ty>::$from_bytes(unsafe {
372 *(self.try_read_exact(mem::size_of::<$ty>())?.as_ptr()
373 as *const [u8; mem::size_of::<$ty>()])
374 }))
375 }
376 }
377}
378
379pub trait ReadBytesExt<'a>: ReadBytes<'a> {
400 fn read_u8(&mut self) -> u8 {
406 self.read_exact(1)[0]
407 }
408
409 fn try_read_u8(&mut self) -> crate::Result<u8> {
414 Ok(self.try_read_exact(1)?[0])
415 }
416
417 fn read_i8(&mut self) -> i8 {
423 self.read_exact(1)[0] as _
424 }
425
426 fn try_read_i8(&mut self) -> crate::Result<i8> {
431 Ok(self.try_read_exact(1)?[0] as _)
432 }
433
434 impl_read! {
435"Reads a little endian `u16` from the underlying buffer.
436
437# Panics
438
439Panics if there are not enough bytes in `self`.",
440 u16,
441 read_u16_le,
442 from_le_bytes,
443 }
444
445 impl_read! {
446"Reads a big endian `u16` from the underlying buffer.
447
448# Panics
449
450Panics if there are not enough bytes in `self`.",
451 u16,
452 read_u16_be,
453 from_be_bytes,
454 }
455
456 impl_try_read! {
457"Attempts to read a little endian `u16` from the underlying buffer.
458
459If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
460 u16,
461 try_read_u16_le,
462 from_le_bytes,
463 }
464
465 impl_try_read! {
466"Attempts to read a big endian `u16` from the underlying buffer.
467
468If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
469 u16,
470 try_read_u16_be,
471 from_be_bytes,
472 }
473
474 impl_read! {
475"Reads a little endian `i16` from the underlying buffer.
476
477# Panics
478
479Panics if there are not enough bytes in `self`.",
480 i16,
481 read_i16_le,
482 from_le_bytes,
483 }
484
485 impl_read! {
486"Reads a big endian `i16` from the underlying buffer.
487
488# Panics
489
490Panics if there are not enough bytes in `self`.",
491 i16,
492 read_i16_be,
493 from_be_bytes,
494 }
495
496 impl_try_read! {
497"Attempts to read a little endian `i16` from the underlying buffer.
498
499If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
500 i16,
501 try_read_i16_le,
502 from_le_bytes,
503 }
504
505 impl_try_read! {
506"Attempts to read a little endian `i16` from the underlying buffer.
507
508If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
509 i16,
510 try_read_i16_be,
511 from_be_bytes,
512 }
513
514 impl_read! {
515"Reads a little endian `u32` from the underlying buffer.
516
517# Panics
518
519Panics if there are not enough bytes in `self`.",
520 u32,
521 read_u32_le,
522 from_le_bytes,
523 }
524
525 impl_read! {
526"Reads a big endian `u32` from the underlying buffer.
527
528# Panics
529
530Panics if there are not enough bytes in `self`.",
531 u32,
532 read_u32_be,
533 from_be_bytes,
534 }
535
536 impl_try_read! {
537"Attempts to read a little endian `u32` from the underlying buffer.
538
539If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
540 u32,
541 try_read_u32_le,
542 from_le_bytes,
543 }
544
545 impl_try_read! {
546"Attempts to read a big endian `u32` from the underlying buffer.
547
548If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
549 u32,
550 try_read_u32_be,
551 from_be_bytes,
552 }
553
554 impl_read! {
555"Reads a little endian `i32` from the underlying buffer.
556
557# Panics
558
559Panics if there are not enough bytes in `self`.",
560 i32,
561 read_i32_le,
562 from_le_bytes,
563 }
564
565 impl_read! {
566"Reads a big endian `i32` from the underlying buffer.
567
568# Panics
569
570Panics if there are not enough bytes in `self`.",
571 i32,
572 read_i32_be,
573 from_be_bytes,
574 }
575
576 impl_try_read! {
577"Attempts to read a little endian `i32` from the underlying buffer.
578
579If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
580 i32,
581 try_read_i32_le,
582 from_le_bytes,
583 }
584
585 impl_try_read! {
586"Attempts to read a big endian `i32` from the underlying buffer.
587
588If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
589 i32,
590 try_read_i32_be,
591 from_be_bytes,
592 }
593
594 impl_read! {
595"Reads a little endian `u64` from the underlying buffer.
596
597# Panics
598
599Panics if there are not enough bytes in `self`.",
600 u64,
601 read_u64_le,
602 from_le_bytes,
603 }
604
605 impl_read! {
606"Reads a big endian `u64` from the underlying buffer.
607
608# Panics
609
610Panics if there are not enough bytes in `self`.",
611 u64,
612 read_u64_be,
613 from_be_bytes,
614 }
615
616 impl_try_read! {
617"Attempts to read a little endian `u64` from the underlying buffer.
618
619If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
620 u64,
621 try_read_u64_le,
622 from_le_bytes,
623 }
624
625 impl_try_read! {
626"Attempts to read a big endian `u64` from the underlying buffer.
627
628If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
629 u64,
630 try_read_u64_be,
631 from_be_bytes,
632 }
633
634 impl_read! {
635"Reads a little endian `i64` from the underlying buffer.
636
637# Panics
638
639Panics if there are not enough bytes in `self`.",
640 i64,
641 read_i64_le,
642 from_le_bytes,
643 }
644
645 impl_read! {
646"Reads a big endian `i64` from the underlying buffer.
647
648# Panics
649
650Panics if there are not enough bytes in `self`.",
651 i64,
652 read_i64_be,
653 from_be_bytes,
654 }
655
656 impl_try_read! {
657"Attempts to read a little endian `i64` from the underlying buffer.
658
659If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
660 i64,
661 try_read_i64_le,
662 from_le_bytes,
663 }
664
665 impl_try_read! {
666"Attempts to read a big endian `i64` from the underlying buffer.
667
668If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
669 i64,
670 try_read_i64_be,
671 from_be_bytes,
672 }
673
674 impl_read! {
675"Reads a little endian `u128` from the underlying buffer.
676
677# Panics
678
679Panics if there are not enough bytes in `self`.",
680 u128,
681 read_u128_le,
682 from_le_bytes,
683 }
684
685 impl_read! {
686"Reads a big endian `u128` from the underlying buffer.
687
688# Panics
689
690Panics if there are not enough bytes in `self`.",
691 u128,
692 read_u128_be,
693 from_be_bytes,
694 }
695
696 impl_try_read! {
697"Attempts to read a little endian `u128` from the underlying buffer.
698
699If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
700 u128,
701 try_read_u128_le,
702 from_le_bytes,
703 }
704
705 impl_try_read! {
706"Attempts to read a big endian `u128` from the underlying buffer.
707
708If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
709 u128,
710 try_read_u128_be,
711 from_be_bytes,
712 }
713
714 impl_read! {
715"Reads a little endian `i128` from the underlying buffer.
716
717# Panics
718
719Panics if there are not enough bytes in `self`.",
720 i128,
721 read_i128_le,
722 from_le_bytes,
723 }
724
725 impl_read! {
726"Reads a big endian `i128` from the underlying buffer.
727
728# Panics
729
730Panics if there are not enough bytes in `self`.",
731 i128,
732 read_i128_be,
733 from_be_bytes,
734 }
735
736 impl_try_read! {
737"Attempts to read a little endian `i128` from the underlying buffer.
738
739If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
740 i128,
741 try_read_i128_le,
742 from_le_bytes,
743 }
744
745 impl_try_read! {
746"Attempts to read a big endian `i128` from the underlying buffer.
747
748If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
749 i128,
750 try_read_i128_be,
751 from_be_bytes,
752 }
753
754 fn read_f32_le(&mut self) -> f32 {
760 f32::from_bits(self.read_u32_le())
761 }
762
763 fn read_f32_be(&mut self) -> f32 {
769 f32::from_bits(self.read_u32_be())
770 }
771
772 fn try_read_f32_le(&mut self) -> crate::Result<f32> {
778 Ok(f32::from_bits(self.try_read_u32_le()?))
779 }
780
781 fn try_read_f32_be(&mut self) -> crate::Result<f32> {
786 Ok(f32::from_bits(self.try_read_u32_be()?))
787 }
788
789 fn read_f64_le(&mut self) -> f64 {
795 f64::from_bits(self.read_u64_le())
796 }
797
798 fn read_f64_be(&mut self) -> f64 {
804 f64::from_bits(self.read_u64_be())
805 }
806
807 fn try_read_f64_le(&mut self) -> crate::Result<f64> {
813 Ok(f64::from_bits(self.try_read_u64_le()?))
814 }
815
816 fn try_read_f64_be(&mut self) -> crate::Result<f64> {
821 Ok(f64::from_bits(self.try_read_u64_be()?))
822 }
823}
824
825impl<'a, R: ReadBytes<'a>> ReadBytesExt<'a> for R {}
826
827#[derive(Debug, Clone, Eq, PartialEq)]
873pub struct Reader<'a, R: ReadBytes<'a>>(R, usize, PhantomData<&'a ()>);
874
875impl<'a, R: ReadBytes<'a>> Reader<'a, R> {
876 #[inline]
890 pub fn new(reader: R) -> Self {
891 Self(reader, 0, PhantomData)
892 }
893
894 #[inline]
909 pub fn num_bytes_read(&self) -> usize {
910 self.1
911 }
912
913 #[inline]
931 pub fn into_inner(self) -> R {
932 self.0
933 }
934}
935
936impl<'a, R: ReadBytes<'a>> AsRef<[u8]> for Reader<'a, R> {
937 fn as_ref(&self) -> &[u8] {
938 self.0.as_ref()
939 }
940}
941
942impl<'a, R: ReadBytes<'a>> ReadBytes<'a> for Reader<'a, R> {
943 fn read_exact(&mut self, n: usize) -> &'a [u8] {
944 self.1 += n;
945 self.0.read_exact(n)
946 }
947
948 fn try_read_exact(&mut self, n: usize) -> crate::Result<&'a [u8]> {
949 match self.0.try_read_exact(n) {
950 res @ Ok(_) => {
951 self.1 += n;
952 res
953 }
954 res @ Err(_) => res,
955 }
956 }
957}
958
959#[cfg(feature = "std")]
960impl<'a, R: ReadBytes<'a>> io::Read for Reader<'a, R> {
961 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
962 let n = ::core::cmp::min(buf.len(), self.as_ref().len());
963 buf[..n].copy_from_slice(<Self as ReadBytes>::read_exact(self, n));
964
965 Ok(n)
966 }
967}
968
969pub trait WriteBytes: AsMut<[u8]> {
1019 fn write_exact(&mut self, buf: &[u8]);
1025
1026 fn try_write_exact(&mut self, buf: &[u8]) -> crate::Result<()> {
1031 if buf.len() > self.as_mut().len() {
1032 Err(Error::EndOfStream)
1033 } else {
1034 self.write_exact(buf);
1035 Ok(())
1036 }
1037 }
1038}
1039
1040impl WriteBytes for &'_ mut [u8] {
1041 fn write_exact(&mut self, buf: &[u8]) {
1042 let (a, b) = mem::replace(self, &mut []).split_at_mut(buf.len());
1043 a.copy_from_slice(&buf);
1044 *self = b;
1045 }
1046}
1047
1048#[cfg(any(feature = "std", feature = "alloc"))]
1049impl WriteBytes for Vec<u8> {
1050 fn write_exact(&mut self, buf: &[u8]) {
1051 self.extend_from_slice(buf);
1052 }
1053
1054 fn try_write_exact(&mut self, buf: &[u8]) -> crate::Result<()> {
1055 self.write_exact(buf);
1056 Ok(())
1057 }
1058}
1059
1060impl<W: WriteBytes> WriteBytes for &'_ mut W {
1061 fn write_exact(&mut self, buf: &[u8]) {
1062 (**self).write_exact(buf)
1063 }
1064
1065 fn try_write_exact(&mut self, buf: &[u8]) -> crate::Result<()> {
1066 (**self).try_write_exact(buf)
1067 }
1068}
1069
1070macro_rules! impl_write {
1077 ($doc:literal, $ty:ty, $fn:ident, $to_bytes:ident $( , )?) => {
1078 #[doc = $doc]
1079 #[inline]
1080 fn $fn(&mut self, n: $ty) {
1081 self.write_exact(&n.$to_bytes()[..]);
1082 }
1083 }
1084}
1085
1086macro_rules! impl_try_write {
1087 ($doc:literal, $ty:ty, $fn:ident, $to_bytes:ident $( , )?) => {
1088 #[doc = $doc]
1089 #[inline]
1090 fn $fn(&mut self, n: $ty) -> crate::Result<()> {
1091 self.try_write_exact(&n.$to_bytes()[..])?;
1092 Ok(())
1093 }
1094 }
1095}
1096
1097pub trait WriteBytesExt: WriteBytes {
1122 #[inline]
1128 fn write_u8(&mut self, n: u8) {
1129 self.write_exact(&[n]);
1130 }
1131
1132 #[inline]
1137 fn try_write_u8(&mut self, n: u8) -> crate::Result<()> {
1138 self.try_write_exact(&[n])?;
1139 Ok(())
1140 }
1141
1142 #[inline]
1148 fn write_i8(&mut self, n: i8) {
1149 self.write_exact(&[n as _]);
1150 }
1151
1152 #[inline]
1157 fn try_write_i8(&mut self, n: i8) -> crate::Result<()> {
1158 self.try_write_exact(&[n as _])?;
1159 Ok(())
1160 }
1161
1162 impl_write! {
1163"Writes a `u16` into the underlying buffer in little endian byte order.
1164
1165# Panics
1166
1167Panics if there are not enough bytes in `self`.",
1168 u16,
1169 write_u16_le,
1170 to_le_bytes,
1171 }
1172
1173 impl_write! {
1174"Writes a `u16` into the underlying buffer in big endian byte order.
1175
1176# Panics
1177
1178Panics if there are not enough bytes in `self`.",
1179 u16,
1180 write_u16_be,
1181 to_be_bytes,
1182 }
1183
1184 impl_try_write! {
1185"Attempts to write a `u16` into the underlying buffer in little endian byte order.
1186
1187If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1188 u16,
1189 try_write_u16_le,
1190 to_le_bytes,
1191 }
1192
1193 impl_try_write! {
1194"Attempts to write a `u16` into the underlying buffer in big endian byte order.
1195
1196If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1197 u16,
1198 try_write_u16_be,
1199 to_be_bytes,
1200 }
1201
1202 impl_write! {
1203"Writes an `i16` into the underlying buffer in little endian byte order.
1204
1205# Panics
1206
1207Panics if there are not enough bytes in `self`.",
1208 i16,
1209 write_i16_le,
1210 to_le_bytes,
1211 }
1212
1213 impl_write! {
1214"Writes an `i16` into the underlying buffer in big endian byte order.
1215
1216# Panics
1217
1218Panics if there are not enough bytes in `self`.",
1219 i16,
1220 write_i16_be,
1221 to_be_bytes,
1222 }
1223
1224 impl_try_write! {
1225"Attempts to write an `i16` into the underlying buffer in little endian byte order.
1226
1227If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1228 i16,
1229 try_write_i16_le,
1230 to_le_bytes,
1231 }
1232
1233 impl_try_write! {
1234"Attempts to write an `i16` into the underlying buffer in big endian byte order.
1235
1236If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1237 i16,
1238 try_write_i16_be,
1239 to_be_bytes,
1240 }
1241
1242 impl_write! {
1243"Writes a `u32` into the underlying buffer in little endian byte order.
1244
1245# Panics
1246
1247Panics if there are not enough bytes in `self`.",
1248 u32,
1249 write_u32_le,
1250 to_le_bytes,
1251 }
1252
1253 impl_write! {
1254"Writes a `u32` into the underlying buffer in big endian byte order.
1255
1256# Panics
1257
1258Panics if there are not enough bytes in `self`.",
1259 u32,
1260 write_u32_be,
1261 to_be_bytes,
1262 }
1263
1264 impl_try_write! {
1265"Attempts to write a `u32` into the underlying buffer in little endian byte order.
1266
1267If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1268 u32,
1269 try_write_u32_le,
1270 to_le_bytes,
1271 }
1272
1273 impl_try_write! {
1274"Attempts to write a `u32` into the underlying buffer in big endian byte order.
1275
1276If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1277 u32,
1278 try_write_u32_be,
1279 to_be_bytes,
1280 }
1281
1282 impl_write! {
1283"Writes an `i32` into the underlying buffer in little endian byte order.
1284
1285# Panics
1286
1287Panics if there are not enough bytes in `self`.",
1288 i32,
1289 write_i32_le,
1290 to_le_bytes,
1291 }
1292
1293 impl_write! {
1294"Writes an `i32` into the underlying buffer in big endian byte order.
1295
1296# Panics
1297
1298Panics if there are not enough bytes in `self`.",
1299 i32,
1300 write_i32_be,
1301 to_be_bytes,
1302 }
1303
1304 impl_try_write! {
1305"Attempts to write an `i32` into the underlying buffer in little endian byte order.
1306
1307If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1308 i32,
1309 try_write_i32_le,
1310 to_le_bytes,
1311 }
1312
1313 impl_try_write! {
1314"Attempts to write an `i32` into the underlying buffer in big endian byte order.
1315
1316If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1317 i32,
1318 try_write_i32_be,
1319 to_be_bytes,
1320 }
1321
1322 impl_write! {
1323"Writes a `u64` into the underlying buffer in little endian byte order.
1324
1325# Panics
1326
1327Panics if there are not enough bytes in `self`.",
1328 u64,
1329 write_u64_le,
1330 to_le_bytes,
1331 }
1332
1333 impl_write! {
1334"Writes a `u64` into the underlying buffer in big endian byte order.
1335
1336# Panics
1337
1338Panics if there are not enough bytes in `self`.",
1339 u64,
1340 write_u64_be,
1341 to_be_bytes,
1342 }
1343
1344 impl_try_write! {
1345"Attempts to write a `u64` into the underlying buffer in little endian byte order.
1346
1347If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1348 u64,
1349 try_write_u64_le,
1350 to_le_bytes,
1351 }
1352
1353 impl_try_write! {
1354"Attempts to write a `u64` into the underlying buffer in big endian byte order.
1355
1356If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1357 u64,
1358 try_write_u64_be,
1359 to_be_bytes,
1360 }
1361
1362 impl_write! {
1363"Writes an `i64` into the underlying buffer in little endian byte order.
1364
1365# Panics
1366
1367Panics if there are not enough bytes in `self`.",
1368 i64,
1369 write_i64_le,
1370 to_le_bytes,
1371 }
1372
1373 impl_write! {
1374"Writes an `i64` into the underlying buffer in big endian byte order.
1375
1376# Panics
1377
1378Panics if there are not enough bytes in `self`.",
1379 i64,
1380 write_i64_be,
1381 to_be_bytes,
1382 }
1383
1384 impl_try_write! {
1385"Attempts to write an `i64` into the underlying buffer in little endian byte order.
1386
1387If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1388 i64,
1389 try_write_i64_le,
1390 to_le_bytes,
1391 }
1392
1393 impl_try_write! {
1394"Attempts to write an `i64` into the underlying buffer in big endian byte order.
1395
1396If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1397 i64,
1398 try_write_i64_be,
1399 to_be_bytes,
1400 }
1401
1402 impl_write! {
1403"Writes a `u128` into the underlying buffer in little endian byte order.
1404
1405# Panics
1406
1407Panics if there are not enough bytes in `self`.",
1408 u128,
1409 write_u128_le,
1410 to_le_bytes,
1411 }
1412
1413 impl_write! {
1414"Writes a `u128` into the underlying buffer in big endian byte order.
1415
1416# Panics
1417
1418Panics if there are not enough bytes in `self`.",
1419 u128,
1420 write_u128_be,
1421 to_be_bytes,
1422 }
1423
1424 impl_try_write! {
1425"Attempts to write a `u128` into the underlying buffer in little endian byte order.
1426
1427If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1428 u128,
1429 try_write_u128_le,
1430 to_le_bytes,
1431 }
1432
1433 impl_try_write! {
1434"Attempts to write a `u128` into the underlying buffer in big endian byte order.
1435
1436If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1437 u128,
1438 try_write_u128_be,
1439 to_be_bytes,
1440 }
1441
1442 impl_write! {
1443"Writes an `i128` into the underlying buffer in little endian byte order.
1444
1445# Panics
1446
1447Panics if there are not enough bytes in `self`.",
1448 i128,
1449 write_i128_le,
1450 to_le_bytes,
1451 }
1452
1453 impl_write! {
1454"Writes an `i128` into the underlying buffer in big endian byte order.
1455
1456# Panics
1457
1458Panics if there are not enough bytes in `self`.",
1459 i128,
1460 write_i128_be,
1461 to_be_bytes,
1462 }
1463
1464 impl_try_write! {
1465"Attempts to write an `i128` into the underlying buffer in little endian byte order.
1466
1467If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1468 i128,
1469 try_write_i128_le,
1470 to_le_bytes,
1471 }
1472
1473 impl_try_write! {
1474"Attempts to write an `i128` into the underlying buffer in big endian byte order.
1475
1476If there are not enough bytes in `self` this function will return `Error::EndOfStream`.",
1477 i128,
1478 try_write_i128_be,
1479 to_be_bytes,
1480 }
1481
1482 fn write_f32_le(&mut self, n: f32) {
1489 self.write_u32_le(n.to_bits());
1490 }
1491
1492 fn write_f32_be(&mut self, n: f32) {
1499 self.write_u32_be(n.to_bits());
1500 }
1501
1502 fn try_write_f32_le(&mut self, n: f32) -> crate::Result<()> {
1507 self.try_write_u32_le(n.to_bits())
1508 }
1509
1510 fn try_write_f32_be(&mut self, n: f32) -> crate::Result<()> {
1516 self.try_write_u32_be(n.to_bits())
1517 }
1518
1519 fn write_f64_le(&mut self, n: f64) {
1526 self.write_u64_le(n.to_bits());
1527 }
1528
1529 fn write_f64_be(&mut self, n: f64) {
1536 self.write_u64_be(n.to_bits());
1537 }
1538
1539 fn try_write_f64_le(&mut self, n: f64) -> crate::Result<()> {
1544 self.try_write_u64_le(n.to_bits())
1545 }
1546
1547 fn try_write_f64_be(&mut self, n: f64) -> crate::Result<()> {
1553 self.try_write_u64_be(n.to_bits())
1554 }
1555}
1556
1557impl<W: WriteBytes> WriteBytesExt for W {}
1558
1559#[derive(Debug, Clone, Eq, PartialEq, Hash)]
1609pub struct Writer<W: WriteBytes>(W, usize);
1610
1611impl<W: WriteBytes> Writer<W> {
1612 #[inline]
1626 pub fn new(writer: W) -> Self {
1627 Self(writer, 0)
1628 }
1629
1630 #[inline]
1645 pub fn num_bytes_written(&self) -> usize {
1646 self.1
1647 }
1648
1649 #[inline]
1665 pub fn into_inner(self) -> W {
1666 self.0
1667 }
1668}
1669
1670impl<W: WriteBytes> AsMut<[u8]> for Writer<W> {
1671 fn as_mut(&mut self) -> &mut [u8] {
1672 self.0.as_mut()
1673 }
1674}
1675
1676impl<W: WriteBytes> WriteBytes for Writer<W> {
1677 fn write_exact(&mut self, buf: &[u8]) {
1678 self.0.write_exact(buf);
1679 self.1 += buf.len();
1680 }
1681
1682 fn try_write_exact(&mut self, buf: &[u8]) -> crate::Result<()> {
1683 match self.0.try_write_exact(buf) {
1684 res @ Ok(_) => {
1685 self.1 += buf.len();
1686 res
1687 }
1688 res @ Err(_) => res,
1689 }
1690 }
1691}
1692
1693#[cfg(feature = "std")]
1694impl<W: WriteBytes> io::Write for Writer<W> {
1695 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
1696 let n = ::core::cmp::min(data.len(), self.as_mut().len());
1697 <Self as WriteBytes>::write_exact(self, &data[..n]);
1698
1699 Ok(n)
1700 }
1701
1702 fn flush(&mut self) -> io::Result<()> {
1703 Ok(())
1704 }
1705}
1706
1707#[cfg(test)]
1716mod test {
1717 #![allow(unused_imports)]
1718
1719 use super::*;
1720
1721 #[cfg(feature = "std")]
1722 #[test]
1723 fn io_error_from_error_end_of_stream() {
1724 let err: io::Error = Error::EndOfStream.into();
1725 assert_eq!(err.kind(), io::ErrorKind::UnexpectedEof);
1726 }
1727
1728 #[cfg(feature = "std")]
1729 #[test]
1730 #[should_panic]
1731 fn io_error_from_error_nonexhaustive() {
1732 let _: io::Error = Error::_nonexhaustive(()).into();
1733 }
1734
1735 #[cfg(feature = "std")]
1736 #[test]
1737 fn display_error_end_of_stream() {
1738 use std::string::ToString;
1739
1740 assert_eq!(Error::EndOfStream.to_string(), "unexpected end of stream");
1741 }
1742
1743 #[cfg(feature = "std")]
1744 #[test]
1745 #[should_panic]
1746 fn display_error_nonexhaustive() {
1747 use std::string::ToString;
1748
1749 let _ = Error::_nonexhaustive(()).to_string();
1750 }
1751}