Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bincode-2.0.1/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![warn(missing_docs, unused_lifetimes)]
3
#![cfg_attr(docsrs, feature(doc_cfg))]
4
5
//! Bincode is a crate for encoding and decoding using a tiny binary
6
//! serialization strategy.  Using it, you can easily go from having
7
//! an object in memory, quickly serialize it to bytes, and then
8
//! deserialize it back just as fast!
9
//!
10
//! If you're coming from bincode 1, check out our [migration guide](migration_guide/index.html)
11
//!
12
//! # Serde
13
//!
14
//! Starting from bincode 2, serde is now an optional dependency. If you want to use serde, please enable the `serde` feature. See [Features](#features) for more information.
15
//!
16
//! # Features
17
//!
18
//! |Name  |Default?|Affects MSRV?|Supported types for Encode/Decode|Enabled methods                                                  |Other|
19
//! |------|--------|-------------|-----------------------------------------|-----------------------------------------------------------------|-----|
20
//! |std   | Yes    | No          |`HashMap` and `HashSet`|`decode_from_std_read` and `encode_into_std_write`|
21
//! |alloc | Yes    | No          |All common containers in alloc, like `Vec`, `String`, `Box`|`encode_to_vec`|
22
//! |atomic| Yes    | No          |All `Atomic*` integer types, e.g. `AtomicUsize`, and `AtomicBool`||
23
//! |derive| Yes    | No          |||Enables the `BorrowDecode`, `Decode` and `Encode` derive macros|
24
//! |serde | No     | Yes (MSRV reliant on serde)|`Compat` and `BorrowCompat`, which will work for all types that implement serde's traits|serde-specific encode/decode functions in the [serde] module|Note: There are several [known issues](serde/index.html#known-issues) when using serde and bincode|
25
//!
26
//! # Which functions to use
27
//!
28
//! Bincode has a couple of pairs of functions that are used in different situations.
29
//!
30
//! |Situation|Encode|Decode|
31
//! |---|---|---
32
//! |You're working with [`fs::File`] or [`net::TcpStream`]|[`encode_into_std_write`]|[`decode_from_std_read`]|
33
//! |you're working with in-memory buffers|[`encode_to_vec`]|[`decode_from_slice`]|
34
//! |You want to use a custom [Reader] and [Writer]|[`encode_into_writer`]|[`decode_from_reader`]|
35
//! |You're working with pre-allocated buffers or on embedded targets|[`encode_into_slice`]|[`decode_from_slice`]|
36
//!
37
//! **Note:** If you're using `serde`, use `bincode::serde::...` instead of `bincode::...`
38
//!
39
//! # Example
40
//!
41
//! ```rust
42
//! let mut slice = [0u8; 100];
43
//!
44
//! // You can encode any type that implements `Encode`.
45
//! // You can automatically implement this trait on custom types with the `derive` feature.
46
//! let input = (
47
//!     0u8,
48
//!     10u32,
49
//!     10000i128,
50
//!     'a',
51
//!     [0u8, 1u8, 2u8, 3u8]
52
//! );
53
//!
54
//! let length = bincode::encode_into_slice(
55
//!     input,
56
//!     &mut slice,
57
//!     bincode::config::standard()
58
//! ).unwrap();
59
//!
60
//! let slice = &slice[..length];
61
//! println!("Bytes written: {:?}", slice);
62
//!
63
//! // Decoding works the same as encoding.
64
//! // The trait used is `Decode`, and can also be automatically implemented with the `derive` feature.
65
//! let decoded: (u8, u32, i128, char, [u8; 4]) = bincode::decode_from_slice(slice, bincode::config::standard()).unwrap().0;
66
//!
67
//! assert_eq!(decoded, input);
68
//! ```
69
//!
70
//! [`fs::File`]: std::fs::File
71
//! [`net::TcpStream`]: std::net::TcpStream
72
//!
73
74
#![doc(html_root_url = "https://docs.rs/bincode/2.0.1")]
75
#![crate_name = "bincode"]
76
#![crate_type = "rlib"]
77
78
#[cfg(feature = "alloc")]
79
extern crate alloc;
80
#[cfg(any(feature = "std", test))]
81
extern crate std;
82
83
mod atomic;
84
mod features;
85
pub(crate) mod utils;
86
pub(crate) mod varint;
87
88
use de::{read::Reader, Decoder};
89
use enc::write::Writer;
90
91
#[cfg(any(
92
    feature = "alloc",
93
    feature = "std",
94
    feature = "derive",
95
    feature = "serde"
96
))]
97
pub use features::*;
98
99
pub mod config;
100
#[macro_use]
101
pub mod de;
102
pub mod enc;
103
pub mod error;
104
105
pub use de::{BorrowDecode, Decode};
106
pub use enc::Encode;
107
108
use config::Config;
109
110
/// Encode the given value into the given slice. Returns the amount of bytes that have been written.
111
///
112
/// See the [config] module for more information on configurations.
113
///
114
/// [config]: config/index.html
115
0
pub fn encode_into_slice<E: enc::Encode, C: Config>(
116
0
    val: E,
117
0
    dst: &mut [u8],
118
0
    config: C,
119
0
) -> Result<usize, error::EncodeError> {
120
0
    let writer = enc::write::SliceWriter::new(dst);
121
0
    let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
122
0
    val.encode(&mut encoder)?;
123
0
    Ok(encoder.into_writer().bytes_written())
124
0
}
125
126
/// Encode the given value into a custom [Writer].
127
///
128
/// See the [config] module for more information on configurations.
129
///
130
/// [config]: config/index.html
131
0
pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
132
0
    val: E,
133
0
    writer: W,
134
0
    config: C,
135
0
) -> Result<(), error::EncodeError> {
136
0
    let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
137
0
    val.encode(&mut encoder)?;
138
0
    Ok(())
139
0
}
140
141
/// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read.
142
///
143
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
144
///
145
/// See the [config] module for more information on configurations.
146
///
147
/// [config]: config/index.html
148
0
pub fn decode_from_slice<D: de::Decode<()>, C: Config>(
149
0
    src: &[u8],
150
0
    config: C,
151
0
) -> Result<(D, usize), error::DecodeError> {
152
0
    decode_from_slice_with_context(src, config, ())
153
0
}
154
155
/// Attempt to decode a given type `D` from the given slice with `Context`. Returns the decoded output and the amount of bytes read.
156
///
157
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
158
///
159
/// See the [config] module for more information on configurations.
160
///
161
/// [config]: config/index.html
162
0
pub fn decode_from_slice_with_context<Context, D: de::Decode<Context>, C: Config>(
163
0
    src: &[u8],
164
0
    config: C,
165
0
    context: Context,
166
0
) -> Result<(D, usize), error::DecodeError> {
167
0
    let reader = de::read::SliceReader::new(src);
168
0
    let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
169
0
    let result = D::decode(&mut decoder)?;
170
0
    let bytes_read = src.len() - decoder.reader().slice.len();
171
0
    Ok((result, bytes_read))
172
0
}
173
174
/// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read.
175
///
176
/// See the [config] module for more information on configurations.
177
///
178
/// [config]: config/index.html
179
0
pub fn borrow_decode_from_slice<'a, D: de::BorrowDecode<'a, ()>, C: Config>(
180
0
    src: &'a [u8],
181
0
    config: C,
182
0
) -> Result<(D, usize), error::DecodeError> {
183
0
    borrow_decode_from_slice_with_context(src, config, ())
184
0
}
185
186
/// Attempt to decode a given type `D` from the given slice with `Context`. Returns the decoded output and the amount of bytes read.
187
///
188
/// See the [config] module for more information on configurations.
189
///
190
/// [config]: config/index.html
191
0
pub fn borrow_decode_from_slice_with_context<
192
0
    'a,
193
0
    Context,
194
0
    D: de::BorrowDecode<'a, Context>,
195
0
    C: Config,
196
0
>(
197
0
    src: &'a [u8],
198
0
    config: C,
199
0
    context: Context,
200
0
) -> Result<(D, usize), error::DecodeError> {
201
0
    let reader = de::read::SliceReader::new(src);
202
0
    let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
203
0
    let result = D::borrow_decode(&mut decoder)?;
204
0
    let bytes_read = src.len() - decoder.reader().slice.len();
205
0
    Ok((result, bytes_read))
206
0
}
207
208
/// Attempt to decode a given type `D` from the given [Reader].
209
///
210
/// See the [config] module for more information on configurations.
211
///
212
/// [config]: config/index.html
213
0
pub fn decode_from_reader<D: de::Decode<()>, R: Reader, C: Config>(
214
0
    reader: R,
215
0
    config: C,
216
0
) -> Result<D, error::DecodeError> {
217
0
    let mut decoder = de::DecoderImpl::<_, C, ()>::new(reader, config, ());
218
0
    D::decode(&mut decoder)
219
0
}
220
221
// TODO: Currently our doctests fail when trying to include the specs because the specs depend on `derive` and `alloc`.
222
// But we want to have the specs in the docs always
223
#[cfg(all(feature = "alloc", feature = "derive", doc))]
224
pub mod spec {
225
    #![doc = include_str!("../docs/spec.md")]
226
}
227
228
#[cfg(doc)]
229
pub mod migration_guide {
230
    #![doc = include_str!("../docs/migration_guide.md")]
231
}
232
233
// Test the examples in readme.md
234
#[cfg(all(feature = "alloc", feature = "derive", doctest))]
235
mod readme {
236
    #![doc = include_str!("../readme.md")]
237
}