1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![allow(internal_features)]
4#![cfg_attr(is_nightly, feature(core_intrinsics))]
5
6#![deny(
84 unreachable_code,
86 improper_ctypes_definitions,
87 future_incompatible,
88 nonstandard_style,
89 rust_2018_idioms,
90 clippy::perf,
91 clippy::correctness,
92 clippy::suspicious,
93 clippy::unwrap_used,
94 clippy::expect_used,
95 clippy::indexing_slicing,
96 clippy::arithmetic_side_effects,
97 clippy::missing_safety_doc,
98 clippy::same_item_push,
99 clippy::implicit_clone,
100 clippy::all,
101 clippy::pedantic,
102 missing_docs,
103 clippy::nursery,
104 clippy::single_call_fn,
105)]
106#![warn(
110 dead_code,
112 warnings,
113 unsafe_code,
114 clippy::dbg_macro,
115 clippy::todo,
116 clippy::cast_possible_truncation,
117 clippy::cast_sign_loss,
118 clippy::cast_possible_wrap,
119 clippy::unnecessary_safety_comment
120)]
121#![allow(
125 clippy::restriction,
126 clippy::inline_always,
127 unused_doc_comments,
128 clippy::empty_line_after_doc_comments
129)]
130#![crate_name = "bincode_next"]
131#![crate_type = "rlib"]
132
133#[cfg(feature = "alloc")]
134extern crate alloc;
135#[cfg(any(feature = "std", test))]
136extern crate std;
137
138mod atomic;
139#[doc(hidden)]
140pub mod error_path;
141mod features;
142#[doc(hidden)]
143pub mod utils;
144pub(crate) mod varint;
145
146use de::Decoder;
147use de::read::Reader;
148use enc::write::Writer;
149
150#[cfg(any(
151 feature = "alloc",
152 feature = "std",
153 feature = "derive",
154 feature = "serde",
155 feature = "zero-copy",
156 feature = "static-size"
157))]
158pub use features::*;
159
160pub const BINCODE_MAJOR_VERSION: u64 = 3;
162
163#[doc(hidden)]
164pub use rapidhash;
165
166pub mod config;
167pub mod fingerprint;
169
170#[macro_use]
171pub mod de;
172pub mod enc;
173pub mod error;
174
175#[cfg(feature = "static-size")]
176pub use static_size::StaticSize;
177
178pub use de::BorrowDecode;
179pub use de::Decode;
180pub use enc::Encode;
181pub use fingerprint::Fingerprint;
182#[cfg(feature = "zero-copy")]
183pub use relative_ptr::ZeroCopy;
184#[cfg(feature = "zero-copy")]
185pub use relative_ptr::ZeroCopyType;
186
187#[cfg(not(any(feature = "std", feature = "serde")))]
188#[cfg(feature = "no-std")]
189use panic_halt as _;
190
191use config::Config;
192use config::internal::InternalFingerprintGuard;
193
194#[inline]
204pub fn encode_into_slice<E: enc::Encode, C: Config>(
205 val: E,
206 dst: &mut [u8],
207 config: C,
208) -> Result<usize, error::EncodeError>
209where
210 C::Mode: config::InternalFingerprintGuard<E, C>,
211{
212 let mut writer = enc::write::SliceWriter::new(dst);
213 C::Mode::encode_check(&config, &mut writer)?;
214 let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
215 val.encode(&mut encoder)?;
216 Ok(encoder.into_writer().bytes_written())
217}
218
219#[inline]
229pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
230 val: E,
231 mut writer: W,
232 config: C,
233) -> Result<(), error::EncodeError>
234where
235 C::Mode: config::InternalFingerprintGuard<E, C>,
236{
237 C::Mode::encode_check(&config, &mut writer)?;
238 let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
239 val.encode(&mut encoder)?;
240 Ok(())
241}
242
243#[inline(always)]
255pub fn decode_from_slice<D: de::Decode<()>, C: Config>(
256 src: &[u8],
257 config: C,
258) -> Result<(D, usize), error::DecodeError>
259where
260 C::Mode: config::InternalFingerprintGuard<D, C>,
261{
262 decode_from_slice_with_context(src, config, ())
263}
264
265#[inline]
277pub fn decode_from_slice_with_context<Context, D: de::Decode<Context>, C: Config>(
278 src: &[u8],
279 config: C,
280 context: Context,
281) -> Result<(D, usize), error::DecodeError>
282where
283 C::Mode: config::InternalFingerprintGuard<D, C>,
284{
285 let mut reader = de::read::SliceReader::new(src);
286 C::Mode::decode_check(&config, &mut reader)?;
287 let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
288 let result = D::decode(&mut decoder)?;
289 let bytes_read = src.len() - decoder.reader().slice.len();
290 Ok((result, bytes_read))
291}
292
293#[inline(always)]
303pub fn borrow_decode_from_slice<'a, D: de::BorrowDecode<'a, ()>, C: Config>(
304 src: &'a [u8],
305 config: C,
306) -> Result<(D, usize), error::DecodeError>
307where
308 C::Mode: config::InternalFingerprintGuard<D, C>,
309{
310 borrow_decode_from_slice_with_context(src, config, ())
311}
312
313#[inline]
323pub fn borrow_decode_from_slice_with_context<
324 'a,
325 Context,
326 D: de::BorrowDecode<'a, Context>,
327 C: Config,
328>(
329 src: &'a [u8],
330 config: C,
331 context: Context,
332) -> Result<(D, usize), error::DecodeError>
333where
334 C::Mode: config::InternalFingerprintGuard<D, C>,
335{
336 let mut reader = de::read::SliceReader::new(src);
337 C::Mode::decode_check(&config, &mut reader)?;
338 let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
339 let result = D::borrow_decode(&mut decoder)?;
340 let bytes_read = src.len() - decoder.reader().slice.len();
341 Ok((result, bytes_read))
342}
343
344#[cfg(feature = "static-size")]
352#[inline(always)]
353pub fn decode_from_slice_static<D, const CAP: usize, C>(
354 src: &[u8; CAP],
355 config: C,
356) -> Result<D, error::DecodeError>
357where
358 D: de::Decode<()> + static_size::StaticSize,
359 C: Config,
360 C::Mode: config::InternalFingerprintGuard<D, C>,
361{
362 const {
363 assert!(D::MAX_SIZE <= CAP, "Buffer too small for target type");
364 }
365 let (val, _) = decode_from_slice(src, config)?;
366 Ok(val)
367}
368
369#[cfg(feature = "static-size")]
379#[inline(always)]
380pub fn decode_from_slice_static_with_context<Context, D, const CAP: usize, C>(
381 src: &[u8; CAP],
382 config: C,
383 context: Context,
384) -> Result<D, error::DecodeError>
385where
386 D: de::Decode<Context> + static_size::StaticSize,
387 C: Config,
388 C::Mode: config::InternalFingerprintGuard<D, C>,
389{
390 const {
391 assert!(D::MAX_SIZE <= CAP, "Buffer too small for target type");
392 }
393 let (val, _) = decode_from_slice_with_context(src, config, context)?;
394 Ok(val)
395}
396
397#[cfg(feature = "static-size")]
406#[inline(always)]
407pub fn borrow_decode_from_slice_static<'a, D, const CAP: usize, C>(
408 src: &'a [u8; CAP],
409 config: C,
410) -> Result<D, error::DecodeError>
411where
412 D: de::BorrowDecode<'a, ()> + static_size::StaticSize,
413 C: Config,
414 C::Mode: config::InternalFingerprintGuard<D, C>,
415{
416 const {
417 assert!(D::MAX_SIZE <= CAP, "Buffer too small for target type");
418 }
419 let (val, _) = borrow_decode_from_slice(src, config)?;
420 Ok(val)
421}
422
423#[cfg(feature = "static-size")]
433#[inline(always)]
434pub fn borrow_decode_from_slice_static_with_context<'a, Context, D, const CAP: usize, C>(
435 src: &'a [u8; CAP],
436 config: C,
437 context: Context,
438) -> Result<D, error::DecodeError>
439where
440 D: de::BorrowDecode<'a, Context> + static_size::StaticSize,
441 C: Config,
442 C::Mode: config::InternalFingerprintGuard<D, C>,
443{
444 const {
445 assert!(D::MAX_SIZE <= CAP, "Buffer too small for target type");
446 }
447 let (val, _) = borrow_decode_from_slice_with_context(src, config, context)?;
448 Ok(val)
449}
450
451#[inline]
461pub fn decode_from_reader<D: de::Decode<()>, R: Reader, C: Config>(
462 mut reader: R,
463 config: C,
464) -> Result<D, error::DecodeError>
465where
466 C::Mode: config::InternalFingerprintGuard<D, C>,
467{
468 C::Mode::decode_check(&config, &mut reader)?;
469 let mut decoder = de::DecoderImpl::<_, C, ()>::new(reader, config, ());
470 D::decode(&mut decoder)
471}
472
473#[cfg(feature = "async-fiber")]
483#[inline(always)]
484pub async fn decode_async<T, R, C>(
485 config: C,
486 reader: R,
487) -> Result<T, crate::error::DecodeError>
488where
489 T: crate::Decode<()>,
490 R: futures_io::AsyncRead + std::marker::Unpin,
491 C: crate::config::Config,
492 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
493{
494 decode_async_with_context::<T, R, C, ()>(config, reader, ()).await
495}
496
497#[cfg(feature = "async-fiber")]
509#[inline]
510pub async fn decode_async_with_context<T, R, C, Context>(
511 config: C,
512 reader: R,
513 context: Context,
514) -> Result<T, crate::error::DecodeError>
515where
516 T: crate::Decode<Context>,
517 R: futures_io::AsyncRead + std::marker::Unpin,
518 C: crate::config::Config,
519 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
520{
521 let bridge = crate::de::async_fiber::AsyncFiberBridge::new(reader);
522 bridge
523 .run(move |fiber_reader| {
524 C::Mode::decode_check(&config, fiber_reader)?;
525 let mut decoder =
526 crate::de::DecoderImpl::<_, C, Context>::new(fiber_reader, config, context);
527 T::decode(&mut decoder)
528 })
529 .await
530}
531
532#[cfg(feature = "async-fiber")]
542#[inline(always)]
543pub async fn decode_async_std<T, R, C>(
544 config: C,
545 reader: R,
546) -> Result<T, crate::error::DecodeError>
547where
548 T: crate::Decode<()>,
549 R: futures_io::AsyncRead + std::marker::Unpin,
550 C: crate::config::Config,
551 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
552{
553 decode_async_with_context::<T, R, C, ()>(config, reader, ()).await
554}
555
556#[cfg(feature = "async-fiber")]
566#[inline(always)]
567pub async fn decode_async_std_with_context<T, R, C, Context>(
568 config: C,
569 reader: R,
570 context: Context,
571) -> Result<T, crate::error::DecodeError>
572where
573 T: crate::Decode<Context>,
574 R: futures_io::AsyncRead + std::marker::Unpin,
575 C: crate::config::Config,
576 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
577{
578 decode_async_with_context::<T, R, C, Context>(config, reader, context).await
579}
580
581#[cfg(feature = "async-fiber")]
591#[inline(always)]
592pub async fn decode_async_smol<T, R, C>(
593 config: C,
594 reader: R,
595) -> Result<T, crate::error::DecodeError>
596where
597 T: crate::Decode<()>,
598 R: futures_io::AsyncRead + std::marker::Unpin,
599 C: crate::config::Config,
600 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
601{
602 decode_async_with_context::<T, R, C, ()>(config, reader, ()).await
603}
604
605#[cfg(feature = "async-fiber")]
615#[inline(always)]
616pub async fn decode_async_smol_with_context<T, R, C, Context>(
617 config: C,
618 reader: R,
619 context: Context,
620) -> Result<T, crate::error::DecodeError>
621where
622 T: crate::Decode<Context>,
623 R: futures_io::AsyncRead + std::marker::Unpin,
624 C: crate::config::Config,
625 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
626{
627 decode_async_with_context::<T, R, C, Context>(config, reader, context).await
628}
629
630#[cfg(all(feature = "tokio", feature = "async-fiber"))]
640#[inline(always)]
641pub async fn decode_async_tokio<T, R, C>(
642 config: C,
643 reader: R,
644) -> Result<T, crate::error::DecodeError>
645where
646 T: crate::Decode<()>,
647 R: tokio::io::AsyncRead + std::marker::Unpin,
648 C: crate::config::Config,
649 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
650{
651 decode_async_tokio_with_context::<T, R, C, ()>(config, reader, ()).await
652}
653
654#[cfg(all(feature = "tokio", feature = "async-fiber"))]
664#[inline(always)]
665pub async fn decode_async_tokio_with_context<T, R, C, Context>(
666 config: C,
667 reader: R,
668 context: Context,
669) -> Result<T, crate::error::DecodeError>
670where
671 T: crate::Decode<Context>,
672 R: tokio::io::AsyncRead + std::marker::Unpin,
673 C: crate::config::Config,
674 C::Mode: crate::config::InternalFingerprintGuard<T, C>,
675{
676 let reader = crate::de::async_fiber::TokioReader(reader);
677 decode_async_with_context::<T, _, C, Context>(config, reader, context).await
678}
679
680#[cfg(all(feature = "async-fiber", feature = "serde"))]
690#[inline(always)]
691pub async fn decode_serde_async<'de, T, R, C>(
692 config: C,
693 reader: R,
694) -> Result<T, crate::error::DecodeError>
695where
696 T: ::serde::Deserialize<'de>,
697 R: futures_io::AsyncRead + std::marker::Unpin,
698 C: crate::config::Config,
699{
700 decode_serde_async_with_context::<'de, T, R, C, ()>(config, reader, ()).await
701}
702
703#[cfg(all(feature = "async-fiber", feature = "serde"))]
713#[inline(always)]
714pub async fn decode_serde_async_std<'de, T, R, C>(
715 config: C,
716 reader: R,
717) -> Result<T, crate::error::DecodeError>
718where
719 T: ::serde::Deserialize<'de>,
720 R: futures_io::AsyncRead + std::marker::Unpin,
721 C: crate::config::Config,
722{
723 decode_serde_async_with_context::<'de, T, R, C, ()>(config, reader, ()).await
724}
725
726#[cfg(all(feature = "async-fiber", feature = "serde"))]
736#[inline(always)]
737pub async fn decode_serde_async_std_with_context<'de, T, R, C, Context>(
738 config: C,
739 reader: R,
740 context: Context,
741) -> Result<T, crate::error::DecodeError>
742where
743 T: ::serde::Deserialize<'de>,
744 R: futures_io::AsyncRead + std::marker::Unpin,
745 C: crate::config::Config,
746{
747 decode_serde_async_with_context::<'de, T, R, C, Context>(config, reader, context).await
748}
749
750#[cfg(all(feature = "async-fiber", feature = "serde"))]
760#[inline(always)]
761pub async fn decode_serde_async_smol<'de, T, R, C>(
762 config: C,
763 reader: R,
764) -> Result<T, crate::error::DecodeError>
765where
766 T: ::serde::Deserialize<'de>,
767 R: futures_io::AsyncRead + std::marker::Unpin,
768 C: crate::config::Config,
769{
770 decode_serde_async_with_context::<'de, T, R, C, ()>(config, reader, ()).await
771}
772
773#[cfg(all(feature = "async-fiber", feature = "serde"))]
783#[inline(always)]
784pub async fn decode_serde_async_smol_with_context<'de, T, R, C, Context>(
785 config: C,
786 reader: R,
787 context: Context,
788) -> Result<T, crate::error::DecodeError>
789where
790 T: ::serde::Deserialize<'de>,
791 R: futures_io::AsyncRead + std::marker::Unpin,
792 C: crate::config::Config,
793{
794 decode_serde_async_with_context::<'de, T, R, C, Context>(config, reader, context).await
795}
796
797#[cfg(all(feature = "async-fiber", feature = "serde"))]
807#[inline]
808pub async fn decode_serde_async_with_context<'de, T, R, C, Context>(
809 config: C,
810 reader: R,
811 context: Context,
812) -> Result<T, crate::error::DecodeError>
813where
814 T: ::serde::Deserialize<'de>,
815 R: futures_io::AsyncRead + std::marker::Unpin,
816 C: crate::config::Config,
817{
818 let bridge = crate::de::async_fiber::AsyncFiberBridge::new(reader);
819 bridge
820 .run(move |fiber_reader| {
821 let decoder =
822 crate::de::DecoderImpl::<_, C, Context>::new(fiber_reader, config, context);
823 let mut serde_decoder = crate::features::serde::OwnedSerdeDecoder { de: decoder };
824 T::deserialize(serde_decoder.as_deserializer())
825 })
826 .await
827}
828
829#[cfg(all(feature = "tokio", feature = "async-fiber", feature = "serde"))]
839#[inline(always)]
840pub async fn decode_serde_tokio_async<'de, T, R, C>(
841 config: C,
842 reader: R,
843) -> Result<T, crate::error::DecodeError>
844where
845 T: ::serde::Deserialize<'de>,
846 R: tokio::io::AsyncRead + std::marker::Unpin,
847 C: crate::config::Config,
848{
849 decode_serde_tokio_async_with_context::<'de, T, R, C, ()>(config, reader, ()).await
850}
851
852#[cfg(all(feature = "tokio", feature = "async-fiber", feature = "serde"))]
862#[inline(always)]
863pub async fn decode_serde_tokio_async_with_context<'de, T, R, C, Context>(
864 config: C,
865 reader: R,
866 context: Context,
867) -> Result<T, crate::error::DecodeError>
868where
869 T: ::serde::Deserialize<'de>,
870 R: tokio::io::AsyncRead + std::marker::Unpin,
871 C: crate::config::Config,
872{
873 let reader = crate::de::async_fiber::TokioReader(reader);
874 decode_serde_async_with_context::<'de, T, _, C, Context>(config, reader, context).await
875}
876
877#[cfg(all(feature = "alloc", feature = "derive", doc))]
878pub mod spec {
879 #![doc = include_str!("../docs/spec.md")]
880}
881
882#[cfg(doc)]
883pub mod migration_guide {
884 #![doc = include_str!("../docs/migration_guide.md")]
885}
886
887#[cfg(all(
889 feature = "std",
890 feature = "derive",
891 feature = "serde",
892 feature = "async-fiber",
893 doctest
894))]
895#[cfg_attr(miri, ignore)]
896mod readme {
897 #![doc = include_str!("../README.md")]
898}