Decode context (#749)

Add an optional context for decoding allowing additional data to be passed to decoded structs.

---------

Co-authored-by: branchseer <dk4rest@gmail.com>
This commit is contained in:
Lena Hellström 2025-03-06 09:54:43 +00:00 committed by GitHub
parent c02d52068e
commit 2c87442fe6
24 changed files with 774 additions and 378 deletions

View File

@ -37,6 +37,7 @@ unty = "0.0.3"
# Used for tests
[dev-dependencies]
ouroboros = "0.18.3"
serde_derive = "1.0"
serde_json = { version = "1.0", default-features = false }
tempfile = "3.2"
@ -47,6 +48,7 @@ chrono = { version = "0.4", features = ["serde"] }
glam = { version = "0.25", features = ["serde"] }
bincode_1 = { version = "1.3", package = "bincode" }
serde = { version = "1.0", features = ["derive"] }
bumpalo = { version = "3.16.0", features = ["collections"] }
[[bench]]
name = "varint"

View File

@ -11,7 +11,7 @@ mod sway;
pub fn test_same_with_config<T, C, O>(t: &T, bincode_1_options: O, bincode_2_config: C)
where
T: bincode_2::Encode
+ bincode_2::Decode
+ bincode_2::Decode<()>
+ serde::Serialize
+ serde::de::DeserializeOwned
+ core::fmt::Debug
@ -60,7 +60,7 @@ where
pub fn test_same<T>(t: T)
where
T: bincode_2::Encode
+ bincode_2::Decode
+ bincode_2::Decode<()>
+ serde::Serialize
+ serde::de::DeserializeOwned
+ core::fmt::Debug

View File

@ -5,6 +5,7 @@ pub struct ContainerAttributes {
pub crate_name: String,
pub bounds: Option<(String, Literal)>,
pub decode_bounds: Option<(String, Literal)>,
pub decode_context: Option<(String, Literal)>,
pub borrow_decode_bounds: Option<(String, Literal)>,
pub encode_bounds: Option<(String, Literal)>,
}
@ -15,6 +16,7 @@ impl Default for ContainerAttributes {
crate_name: "::bincode".to_string(),
bounds: None,
decode_bounds: None,
decode_context: None,
encode_bounds: None,
borrow_decode_bounds: None,
}
@ -56,6 +58,15 @@ impl FromAttribute for ContainerAttributes {
return Err(Error::custom_at("Should be a literal str", val.span()));
}
}
ParsedAttribute::Property(key, val) if key.to_string() == "decode_context" => {
let val_string = val.to_string();
if val_string.starts_with('"') && val_string.ends_with('"') {
result.decode_context =
Some((val_string[1..val_string.len() - 1].to_string(), val));
} else {
return Err(Error::custom_at("Should be a literal str", val.span()));
}
}
ParsedAttribute::Property(key, val) if key.to_string() == "encode_bounds" => {
let val_string = val.to_string();
if val_string.starts_with('"') && val_string.ends_with('"') {

View File

@ -219,25 +219,36 @@ impl DeriveEnum {
pub fn generate_decode(self, generator: &mut Generator) -> Result<()> {
let crate_name = self.attributes.crate_name.as_str();
let decode_context = if let Some((decode_context, _)) = &self.attributes.decode_context {
decode_context.as_str()
} else {
"__Context"
};
// Remember to keep this mostly in sync with generate_borrow_decode
let enum_name = generator.target_name().to_string();
generator
.impl_for(format!("{}::Decode", crate_name))
let mut impl_for = generator.impl_for(format!("{}::Decode", crate_name));
if self.attributes.decode_context.is_none() {
impl_for = impl_for.with_impl_generics(["__Context"]);
}
impl_for
.with_trait_generics([decode_context])
.modify_generic_constraints(|generics, where_constraints| {
if let Some((bounds, lit)) = (self.attributes.decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
where_constraints.clear();
where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?;
} else {
for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::Decode", crate_name))?;
where_constraints.push_constraint(g, format!("{}::Decode<__Context>", crate_name))?;
}
}
Ok(())
})?
.generate_fn("decode")
.with_generic_deps("__D", [format!("{}::de::Decoder", crate_name)])
.with_generic_deps("__D", [format!("{}::de::Decoder<Context = {}>", crate_name, decode_context)])
.with_arg("decoder", "&mut __D")
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", crate_name))
.body(|fn_builder| {
@ -249,7 +260,7 @@ impl DeriveEnum {
} else {
fn_builder
.push_parsed(format!(
"let variant_index = <u32 as {}::Decode>::decode(decoder)?;",
"let variant_index = <u32 as {}::Decode::<__D::Context>>::decode(decoder)?;",
crate_name
))?;
fn_builder.push_parsed("match variant_index")?;
@ -286,13 +297,13 @@ impl DeriveEnum {
if attributes.with_serde {
variant_body
.push_parsed(format!(
"<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?.0,",
"<{0}::serde::Compat<_> as {0}::Decode::<__D::Context>>::decode(decoder)?.0,",
crate_name
))?;
} else {
variant_body
.push_parsed(format!(
"{}::Decode::decode(decoder)?,",
"{}::Decode::<__D::Context>::decode(decoder)?,",
crate_name
))?;
}
@ -318,17 +329,30 @@ impl DeriveEnum {
pub fn generate_borrow_decode(self, generator: &mut Generator) -> Result<()> {
let crate_name = &self.attributes.crate_name;
let decode_context = if let Some((decode_context, _)) = &self.attributes.decode_context {
decode_context.as_str()
} else {
"__Context"
};
// Remember to keep this mostly in sync with generate_decode
let enum_name = generator.target_name().to_string();
generator.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
let mut impl_for = generator
.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
.with_trait_generics([decode_context]);
if self.attributes.decode_context.is_none() {
impl_for = impl_for.with_impl_generics(["__Context"]);
}
impl_for
.modify_generic_constraints(|generics, where_constraints| {
if let Some((bounds, lit)) = (self.attributes.borrow_decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
where_constraints.clear();
where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?;
} else {
for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap();
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de, {}>", crate_name, decode_context)).unwrap();
}
for lt in generics.iter_lifetimes() {
where_constraints.push_parsed_constraint(format!("'__de: '{}", lt.ident))?;
@ -337,7 +361,7 @@ impl DeriveEnum {
Ok(())
})?
.generate_fn("borrow_decode")
.with_generic_deps("__D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
.with_generic_deps("__D", [format!("{}::de::BorrowDecoder<'__de, Context = {}>", crate_name, decode_context)])
.with_arg("decoder", "&mut __D")
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", crate_name))
.body(|fn_builder| {
@ -348,7 +372,7 @@ impl DeriveEnum {
))?;
} else {
fn_builder
.push_parsed(format!("let variant_index = <u32 as {}::Decode>::decode(decoder)?;", crate_name))?;
.push_parsed(format!("let variant_index = <u32 as {}::Decode::<__D::Context>>::decode(decoder)?;", crate_name))?;
fn_builder.push_parsed("match variant_index")?;
fn_builder.group(Delimiter::Brace, |variant_case| {
for (mut variant_index, variant) in self.iter_fields() {
@ -382,9 +406,9 @@ impl DeriveEnum {
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
if attributes.with_serde {
variant_body
.push_parsed(format!("<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?.0,", crate_name))?;
.push_parsed(format!("<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode::<__D::Context>>::borrow_decode(decoder)?.0,", crate_name))?;
} else {
variant_body.push_parsed(format!("{}::BorrowDecode::borrow_decode(decoder)?,", crate_name))?;
variant_body.push_parsed(format!("{}::BorrowDecode::<__D::Context>::borrow_decode(decoder)?,", crate_name))?;
}
}
}

View File

@ -1,6 +1,4 @@
use crate::attribute::{ContainerAttributes, FieldAttributes};
use virtue::generate::Generator;
use virtue::parse::Fields;
use virtue::prelude::*;
pub(crate) struct DeriveStruct {
@ -67,22 +65,32 @@ impl DeriveStruct {
pub fn generate_decode(self, generator: &mut Generator) -> Result<()> {
// Remember to keep this mostly in sync with generate_borrow_decode
let crate_name = &self.attributes.crate_name;
let decode_context = if let Some((decode_context, _)) = &self.attributes.decode_context {
decode_context.as_str()
} else {
"__Context"
};
generator
.impl_for(format!("{}::Decode", crate_name))
let mut impl_for = generator.impl_for(format!("{}::Decode", crate_name));
if self.attributes.decode_context.is_none() {
impl_for = impl_for.with_impl_generics(["__Context"]);
}
impl_for
.with_trait_generics([decode_context])
.modify_generic_constraints(|generics, where_constraints| {
if let Some((bounds, lit)) = (self.attributes.decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
where_constraints.clear();
where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?;
} else {
for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::Decode", crate_name)).unwrap();
where_constraints.push_constraint(g, format!("{}::Decode<{}>", crate_name, decode_context)).unwrap();
}
}
Ok(())
})?
.generate_fn("decode")
.with_generic_deps("__D", [format!("{}::de::Decoder", crate_name)])
.with_generic_deps("__D", [format!("{}::de::Decoder<Context = {}>", crate_name, decode_context)])
.with_arg("decoder", "&mut __D")
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", crate_name))
.body(|fn_body| {
@ -103,9 +111,10 @@ impl DeriveStruct {
if attributes.with_serde {
struct_body
.push_parsed(format!(
"{1}: (<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?).0,",
"{1}: (<{0}::serde::Compat<_> as {0}::Decode::<{2}>>::decode(decoder)?).0,",
crate_name,
field
field,
decode_context,
))?;
} else {
struct_body
@ -131,15 +140,27 @@ impl DeriveStruct {
// Remember to keep this mostly in sync with generate_decode
let crate_name = self.attributes.crate_name;
generator
let decode_context = if let Some((decode_context, _)) = &self.attributes.decode_context {
decode_context.as_str()
} else {
"__Context"
};
let mut impl_for = generator
.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
.with_trait_generics([decode_context]);
if self.attributes.decode_context.is_none() {
impl_for = impl_for.with_impl_generics(["__Context"]);
}
impl_for
.modify_generic_constraints(|generics, where_constraints| {
if let Some((bounds, lit)) = (self.attributes.borrow_decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
where_constraints.clear();
where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?;
} else {
for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap();
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de, {}>", crate_name, decode_context)).unwrap();
}
for lt in generics.iter_lifetimes() {
where_constraints.push_parsed_constraint(format!("'__de: '{}", lt.ident))?;
@ -148,7 +169,7 @@ impl DeriveStruct {
Ok(())
})?
.generate_fn("borrow_decode")
.with_generic_deps("__D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
.with_generic_deps("__D", [format!("{}::de::BorrowDecoder<'__de, Context = {}>", crate_name, decode_context)])
.with_arg("decoder", "&mut __D")
.with_return_type(format!("core::result::Result<Self, {}::error::DecodeError>", crate_name))
.body(|fn_body| {
@ -163,16 +184,18 @@ impl DeriveStruct {
if attributes.with_serde {
struct_body
.push_parsed(format!(
"{1}: (<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?).0,",
"{1}: (<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode::<'_, {2}>>::borrow_decode(decoder)?).0,",
crate_name,
field
field,
decode_context,
))?;
} else {
struct_body
.push_parsed(format!(
"{1}: {0}::BorrowDecode::borrow_decode(decoder)?,",
"{1}: {0}::BorrowDecode::<'_, {2}>::borrow_decode(decoder)?,",
crate_name,
field
field,
decode_context,
))?;
}
}

View File

@ -27,7 +27,7 @@ impl Encode for AtomicBool {
}
#[cfg(target_has_atomic = "8")]
impl Decode for AtomicBool {
impl<Context> Decode<Context> for AtomicBool {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicBool::new(Decode::decode(decoder)?))
}
@ -46,7 +46,7 @@ impl Encode for AtomicU8 {
}
#[cfg(target_has_atomic = "8")]
impl Decode for AtomicU8 {
impl<Context> Decode<Context> for AtomicU8 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicU8::new(Decode::decode(decoder)?))
}
@ -65,7 +65,7 @@ impl Encode for AtomicU16 {
}
#[cfg(target_has_atomic = "16")]
impl Decode for AtomicU16 {
impl<Context> Decode<Context> for AtomicU16 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicU16::new(Decode::decode(decoder)?))
}
@ -84,7 +84,7 @@ impl Encode for AtomicU32 {
}
#[cfg(target_has_atomic = "32")]
impl Decode for AtomicU32 {
impl<Context> Decode<Context> for AtomicU32 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicU32::new(Decode::decode(decoder)?))
}
@ -103,7 +103,7 @@ impl Encode for AtomicU64 {
}
#[cfg(target_has_atomic = "64")]
impl Decode for AtomicU64 {
impl<Context> Decode<Context> for AtomicU64 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicU64::new(Decode::decode(decoder)?))
}
@ -122,7 +122,7 @@ impl Encode for AtomicUsize {
}
#[cfg(target_has_atomic = "ptr")]
impl Decode for AtomicUsize {
impl<Context> Decode<Context> for AtomicUsize {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicUsize::new(Decode::decode(decoder)?))
}
@ -141,7 +141,7 @@ impl Encode for AtomicI8 {
}
#[cfg(target_has_atomic = "8")]
impl Decode for AtomicI8 {
impl<Context> Decode<Context> for AtomicI8 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicI8::new(Decode::decode(decoder)?))
}
@ -160,7 +160,7 @@ impl Encode for AtomicI16 {
}
#[cfg(target_has_atomic = "16")]
impl Decode for AtomicI16 {
impl<Context> Decode<Context> for AtomicI16 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicI16::new(Decode::decode(decoder)?))
}
@ -179,7 +179,7 @@ impl Encode for AtomicI32 {
}
#[cfg(target_has_atomic = "32")]
impl Decode for AtomicI32 {
impl<Context> Decode<Context> for AtomicI32 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicI32::new(Decode::decode(decoder)?))
}
@ -198,7 +198,7 @@ impl Encode for AtomicI64 {
}
#[cfg(target_has_atomic = "64")]
impl Decode for AtomicI64 {
impl<Context> Decode<Context> for AtomicI64 {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicI64::new(Decode::decode(decoder)?))
}
@ -217,7 +217,7 @@ impl Encode for AtomicIsize {
}
#[cfg(target_has_atomic = "ptr")]
impl Decode for AtomicIsize {
impl<Context> Decode<Context> for AtomicIsize {
fn decode<D: crate::de::Decoder>(decoder: &mut D) -> Result<Self, crate::error::DecodeError> {
Ok(AtomicIsize::new(Decode::decode(decoder)?))
}

View File

@ -16,30 +16,35 @@ use crate::{config::Config, error::DecodeError, utils::Sealed};
/// # let slice: &[u8] = &[0, 0, 0, 0];
/// # let some_reader = bincode::de::read::SliceReader::new(slice);
/// use bincode::de::{DecoderImpl, Decode};
/// let mut decoder = DecoderImpl::new(some_reader, bincode::config::standard());
/// let mut context = ();
/// let mut decoder = DecoderImpl::new(some_reader, bincode::config::standard(), &mut context);
/// // this u32 can be any Decode
/// let value = u32::decode(&mut decoder).unwrap();
/// ```
pub struct DecoderImpl<R, C: Config> {
pub struct DecoderImpl<R, C: Config, Context> {
reader: R,
config: C,
bytes_read: usize,
context: Context,
}
impl<R: Reader, C: Config> DecoderImpl<R, C> {
impl<R: Reader, C: Config, Context> DecoderImpl<R, C, Context> {
/// Construct a new Decoder
pub const fn new(reader: R, config: C) -> DecoderImpl<R, C> {
pub fn new(reader: R, config: C, context: Context) -> DecoderImpl<R, C, Context> {
DecoderImpl {
reader,
config,
bytes_read: 0,
context,
}
}
}
impl<R, C: Config> Sealed for DecoderImpl<R, C> {}
impl<R, C: Config, Context> Sealed for DecoderImpl<R, C, Context> {}
impl<'de, R: BorrowReader<'de>, C: Config> BorrowDecoder<'de> for DecoderImpl<R, C> {
impl<'de, R: BorrowReader<'de>, C: Config, Context> BorrowDecoder<'de>
for DecoderImpl<R, C, Context>
{
type BR = R;
fn borrow_reader(&mut self) -> &mut Self::BR {
@ -47,10 +52,11 @@ impl<'de, R: BorrowReader<'de>, C: Config> BorrowDecoder<'de> for DecoderImpl<R,
}
}
impl<R: Reader, C: Config> Decoder for DecoderImpl<R, C> {
impl<R: Reader, C: Config, Context> Decoder for DecoderImpl<R, C, Context> {
type R = R;
type C = C;
type Context = Context;
fn reader(&mut self) -> &mut Self::R {
&mut self.reader
@ -87,4 +93,50 @@ impl<R: Reader, C: Config> Decoder for DecoderImpl<R, C> {
self.bytes_read -= n;
}
}
fn context(&mut self) -> &mut Self::Context {
&mut self.context
}
}
pub struct WithContext<'a, D: ?Sized, C> {
pub(crate) decoder: &'a mut D,
pub(crate) context: C,
}
impl<C, D: Decoder + ?Sized> Sealed for WithContext<'_, D, C> {}
impl<Context, D: Decoder + ?Sized> Decoder for WithContext<'_, D, Context> {
type R = D::R;
type C = D::C;
type Context = Context;
fn context(&mut self) -> &mut Self::Context {
&mut self.context
}
fn reader(&mut self) -> &mut Self::R {
self.decoder.reader()
}
fn config(&self) -> &Self::C {
self.decoder.config()
}
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
self.decoder.claim_bytes_read(n)
}
fn unclaim_bytes_read(&mut self, n: usize) {
self.decoder.unclaim_bytes_read(n)
}
}
impl<'de, C, D: BorrowDecoder<'de>> BorrowDecoder<'de> for WithContext<'_, D, C> {
type BR = D::BR;
fn borrow_reader(&mut self) -> &mut Self::BR {
self.decoder.borrow_reader()
}
}

View File

@ -4,14 +4,14 @@ use crate::error::DecodeError;
macro_rules! impl_tuple {
() => {};
($first:ident $(, $extra:ident)*) => {
impl<'de, $first $(, $extra)*> BorrowDecode<'de> for ($first, $($extra, )*)
impl<'de, $first $(, $extra)*, Context> BorrowDecode<'de, Context> for ($first, $($extra, )*)
where
$first: BorrowDecode<'de>,
$first: BorrowDecode<'de, Context>,
$(
$extra : BorrowDecode<'de>,
$extra : BorrowDecode<'de, Context>,
)*
{
fn borrow_decode<BD: BorrowDecoder<'de>>(decoder: &mut BD) -> Result<Self, DecodeError> {
fn borrow_decode<BD: BorrowDecoder<'de, Context = Context>>(decoder: &mut BD) -> Result<Self, DecodeError> {
Ok((
$first::borrow_decode(decoder)?,
$($extra :: borrow_decode(decoder)?, )*
@ -19,14 +19,14 @@ macro_rules! impl_tuple {
}
}
impl<$first $(, $extra)*> Decode for ($first, $($extra, )*)
impl<Context, $first $(, $extra)*> Decode<Context> for ($first, $($extra, )*)
where
$first: Decode,
$first: Decode<Context>,
$(
$extra : Decode,
$extra : Decode<Context>,
)*
{
fn decode<DE: Decoder>(decoder: &mut DE) -> Result<Self, DecodeError> {
fn decode<DE: Decoder<Context = Context>>(decoder: &mut DE) -> Result<Self, DecodeError> {
Ok((
$first::decode(decoder)?,
$($extra :: decode(decoder)?, )*

View File

@ -18,8 +18,8 @@ use core::{
time::Duration,
};
impl Decode for bool {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for bool {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
match u8::decode(decoder)? {
0 => Ok(false),
1 => Ok(true),
@ -29,9 +29,9 @@ impl Decode for bool {
}
impl_borrow_decode!(bool);
impl Decode for u8 {
impl<Context> Decode<Context> for u8 {
#[inline]
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(1)?;
if let Some(buf) = decoder.reader().peek_read(1) {
let byte = buf[0];
@ -46,8 +46,8 @@ impl Decode for u8 {
}
impl_borrow_decode!(u8);
impl Decode for NonZeroU8 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroU8 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroU8::new(u8::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::U8,
})
@ -55,8 +55,8 @@ impl Decode for NonZeroU8 {
}
impl_borrow_decode!(NonZeroU8);
impl Decode for u16 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for u16 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(2)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -75,8 +75,8 @@ impl Decode for u16 {
}
impl_borrow_decode!(u16);
impl Decode for NonZeroU16 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroU16 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroU16::new(u16::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::U16,
})
@ -84,8 +84,8 @@ impl Decode for NonZeroU16 {
}
impl_borrow_decode!(NonZeroU16);
impl Decode for u32 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for u32 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(4)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -104,8 +104,8 @@ impl Decode for u32 {
}
impl_borrow_decode!(u32);
impl Decode for NonZeroU32 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroU32 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroU32::new(u32::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::U32,
})
@ -113,8 +113,8 @@ impl Decode for NonZeroU32 {
}
impl_borrow_decode!(NonZeroU32);
impl Decode for u64 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for u64 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -133,8 +133,8 @@ impl Decode for u64 {
}
impl_borrow_decode!(u64);
impl Decode for NonZeroU64 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroU64 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroU64::new(u64::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::U64,
})
@ -142,8 +142,8 @@ impl Decode for NonZeroU64 {
}
impl_borrow_decode!(NonZeroU64);
impl Decode for u128 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for u128 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(16)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -162,8 +162,8 @@ impl Decode for u128 {
}
impl_borrow_decode!(u128);
impl Decode for NonZeroU128 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroU128 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroU128::new(u128::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::U128,
})
@ -171,8 +171,8 @@ impl Decode for NonZeroU128 {
}
impl_borrow_decode!(NonZeroU128);
impl Decode for usize {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for usize {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -196,8 +196,8 @@ impl Decode for usize {
}
impl_borrow_decode!(usize);
impl Decode for NonZeroUsize {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroUsize {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroUsize::new(usize::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::Usize,
})
@ -205,8 +205,8 @@ impl Decode for NonZeroUsize {
}
impl_borrow_decode!(NonZeroUsize);
impl Decode for i8 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for i8 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(1)?;
let mut bytes = [0u8; 1];
decoder.reader().read(&mut bytes)?;
@ -215,8 +215,8 @@ impl Decode for i8 {
}
impl_borrow_decode!(i8);
impl Decode for NonZeroI8 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroI8 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroI8::new(i8::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::I8,
})
@ -224,8 +224,8 @@ impl Decode for NonZeroI8 {
}
impl_borrow_decode!(NonZeroI8);
impl Decode for i16 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for i16 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(2)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -244,8 +244,8 @@ impl Decode for i16 {
}
impl_borrow_decode!(i16);
impl Decode for NonZeroI16 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroI16 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroI16::new(i16::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::I16,
})
@ -253,8 +253,8 @@ impl Decode for NonZeroI16 {
}
impl_borrow_decode!(NonZeroI16);
impl Decode for i32 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for i32 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(4)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -273,8 +273,8 @@ impl Decode for i32 {
}
impl_borrow_decode!(i32);
impl Decode for NonZeroI32 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroI32 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroI32::new(i32::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::I32,
})
@ -282,8 +282,8 @@ impl Decode for NonZeroI32 {
}
impl_borrow_decode!(NonZeroI32);
impl Decode for i64 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for i64 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -302,8 +302,8 @@ impl Decode for i64 {
}
impl_borrow_decode!(i64);
impl Decode for NonZeroI64 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroI64 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroI64::new(i64::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::I64,
})
@ -311,8 +311,8 @@ impl Decode for NonZeroI64 {
}
impl_borrow_decode!(NonZeroI64);
impl Decode for i128 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for i128 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(16)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -331,8 +331,8 @@ impl Decode for i128 {
}
impl_borrow_decode!(i128);
impl Decode for NonZeroI128 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroI128 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroI128::new(i128::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::I128,
})
@ -340,8 +340,8 @@ impl Decode for NonZeroI128 {
}
impl_borrow_decode!(NonZeroI128);
impl Decode for isize {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for isize {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
@ -360,8 +360,8 @@ impl Decode for isize {
}
impl_borrow_decode!(isize);
impl Decode for NonZeroIsize {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for NonZeroIsize {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
NonZeroIsize::new(isize::decode(decoder)?).ok_or(DecodeError::NonZeroTypeIsZero {
non_zero_type: IntegerType::Isize,
})
@ -369,8 +369,8 @@ impl Decode for NonZeroIsize {
}
impl_borrow_decode!(NonZeroIsize);
impl Decode for f32 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for f32 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(4)?;
let mut bytes = [0u8; 4];
decoder.reader().read(&mut bytes)?;
@ -382,8 +382,8 @@ impl Decode for f32 {
}
impl_borrow_decode!(f32);
impl Decode for f64 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for f64 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(8)?;
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
@ -395,31 +395,35 @@ impl Decode for f64 {
}
impl_borrow_decode!(f64);
impl<T: Decode> Decode for Wrapping<T> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context, T: Decode<Context>> Decode<Context> for Wrapping<T> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Wrapping(T::decode(decoder)?))
}
}
impl<'de, T: BorrowDecode<'de>> BorrowDecode<'de> for Wrapping<T> {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'de, Context, T: BorrowDecode<'de, Context>> BorrowDecode<'de, Context> for Wrapping<T> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
Ok(Wrapping(T::borrow_decode(decoder)?))
}
}
impl<T: Decode> Decode for Reverse<T> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context, T: Decode<Context>> Decode<Context> for Reverse<T> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Reverse(T::decode(decoder)?))
}
}
impl<'de, T: BorrowDecode<'de>> BorrowDecode<'de> for Reverse<T> {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'de, Context, T: BorrowDecode<'de, Context>> BorrowDecode<'de, Context> for Reverse<T> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
Ok(Reverse(T::borrow_decode(decoder)?))
}
}
impl Decode for char {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for char {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let mut array = [0u8; 4];
// Look at the first byte to see how many bytes must be read
@ -448,26 +452,30 @@ impl Decode for char {
}
impl_borrow_decode!(char);
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a [u8] {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'a, 'de: 'a, Context> BorrowDecode<'de, Context> for &'a [u8] {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = super::decode_slice_len(decoder)?;
decoder.claim_bytes_read(len)?;
decoder.borrow_reader().take_bytes(len)
}
}
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'a, 'de: 'a, Context> BorrowDecode<'de, Context> for &'a str {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let slice = <&[u8]>::borrow_decode(decoder)?;
core::str::from_utf8(slice).map_err(|inner| DecodeError::Utf8 { inner })
}
}
impl<T, const N: usize> Decode for [T; N]
impl<Context, T, const N: usize> Decode<Context> for [T; N]
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
if unty::type_equal::<T, u8>() {
@ -493,11 +501,13 @@ where
}
}
impl<'de, T, const N: usize> BorrowDecode<'de> for [T; N]
impl<'de, T, const N: usize, Context> BorrowDecode<'de, Context> for [T; N]
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
if unty::type_equal::<T, u8>() {
@ -523,25 +533,25 @@ where
}
}
impl Decode for () {
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for () {
fn decode<D: Decoder<Context = Context>>(_: &mut D) -> Result<Self, DecodeError> {
Ok(())
}
}
impl_borrow_decode!(());
impl<T> Decode for core::marker::PhantomData<T> {
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
impl<Context, T> Decode<Context> for core::marker::PhantomData<T> {
fn decode<D: Decoder<Context = Context>>(_: &mut D) -> Result<Self, DecodeError> {
Ok(core::marker::PhantomData)
}
}
impl_borrow_decode!(core::marker::PhantomData<T>, T);
impl<T> Decode for Option<T>
impl<Context, T> Decode<Context> for Option<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
match super::decode_option_variant(decoder, core::any::type_name::<Option<T>>())? {
Some(_) => {
let val = T::decode(decoder)?;
@ -552,11 +562,13 @@ where
}
}
impl<'de, T> BorrowDecode<'de> for Option<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Option<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
match super::decode_option_variant(decoder, core::any::type_name::<Option<T>>())? {
Some(_) => {
let val = T::borrow_decode(decoder)?;
@ -567,12 +579,12 @@ where
}
}
impl<T, U> Decode for Result<T, U>
impl<Context, T, U> Decode<Context> for Result<T, U>
where
T: Decode,
U: Decode,
T: Decode<Context>,
U: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let is_ok = u32::decode(decoder)?;
match is_ok {
0 => {
@ -592,12 +604,14 @@ where
}
}
impl<'de, T, U> BorrowDecode<'de> for Result<T, U>
impl<'de, T, U, Context> BorrowDecode<'de, Context> for Result<T, U>
where
T: BorrowDecode<'de>,
U: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
U: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let is_ok = u32::decode(decoder)?;
match is_ok {
0 => {
@ -617,48 +631,52 @@ where
}
}
impl<T> Decode for Cell<T>
impl<Context, T> Decode<Context> for Cell<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(Cell::new(t))
}
}
impl<'de, T> BorrowDecode<'de> for Cell<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Cell<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(Cell::new(t))
}
}
impl<T> Decode for RefCell<T>
impl<Context, T> Decode<Context> for RefCell<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(RefCell::new(t))
}
}
impl<'de, T> BorrowDecode<'de> for RefCell<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for RefCell<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(RefCell::new(t))
}
}
impl Decode for Duration {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for Duration {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
const NANOS_PER_SEC: u64 = 1_000_000_000;
let secs: u64 = Decode::decode(decoder)?;
let nanos: u32 = Decode::decode(decoder)?;
@ -670,54 +688,58 @@ impl Decode for Duration {
}
impl_borrow_decode!(Duration);
impl<T> Decode for Range<T>
impl<Context, T> Decode<Context> for Range<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let min = T::decode(decoder)?;
let max = T::decode(decoder)?;
Ok(min..max)
}
}
impl<'de, T> BorrowDecode<'de> for Range<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Range<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let min = T::borrow_decode(decoder)?;
let max = T::borrow_decode(decoder)?;
Ok(min..max)
}
}
impl<T> Decode for RangeInclusive<T>
impl<Context, T> Decode<Context> for RangeInclusive<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let min = T::decode(decoder)?;
let max = T::decode(decoder)?;
Ok(RangeInclusive::new(min, max))
}
}
impl<'de, T> BorrowDecode<'de> for RangeInclusive<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for RangeInclusive<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let min = T::borrow_decode(decoder)?;
let max = T::borrow_decode(decoder)?;
Ok(RangeInclusive::new(min, max))
}
}
impl<T> Decode for Bound<T>
impl<T, Context> Decode<Context> for Bound<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
match u32::decode(decoder)? {
0 => Ok(Bound::Unbounded),
1 => Ok(Bound::Included(T::decode(decoder)?)),
@ -731,11 +753,13 @@ where
}
}
impl<'de, T> BorrowDecode<'de> for Bound<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Bound<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
match u32::decode(decoder)? {
0 => Ok(Bound::Unbounded),
1 => Ok(Bound::Included(T::borrow_decode(decoder)?)),

View File

@ -5,7 +5,10 @@ mod impl_core;
mod impl_tuples;
mod impls;
use self::read::{BorrowReader, Reader};
use self::{
decoder::WithContext,
read::{BorrowReader, Reader},
};
use crate::{
config::{Config, InternalLimitConfig},
error::DecodeError,
@ -18,11 +21,13 @@ pub use self::decoder::DecoderImpl;
/// Trait that makes a type able to be decoded, akin to serde's `DeserializeOwned` trait.
///
/// Some types may require specific contexts. For example, to decode arena-based collections, an arena allocator must be provided as a context. In these cases, the context type `Context` should be specified or bounded.
///
/// This trait should be implemented for types which do not have references to data in the reader. For types that contain e.g. `&str` and `&[u8]`, implement [BorrowDecode] instead.
///
/// Whenever you implement `Decode` for your type, the base trait `BorrowDecode` is automatically implemented.
/// Whenever you derive `Decode` for your type, the base trait `BorrowDecode` is automatically implemented.
///
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to your type. Note that if the type contains any lifetimes, `BorrowDecode` will be implemented instead.
/// This trait will be automatically implemented with unbounded `Context` if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to your type. Note that if the type contains any lifetimes, `BorrowDecode` will be implemented instead.
///
/// # Implementing this trait manually
///
@ -44,8 +49,8 @@ pub use self::decoder::DecoderImpl;
/// # pub x: f32,
/// # pub y: f32,
/// # }
/// impl bincode::Decode for Entity {
/// fn decode<D: bincode::de::Decoder>(
/// impl<Context> bincode::Decode<Context> for Entity {
/// fn decode<D: bincode::de::Decoder<Context = Context>>(
/// decoder: &mut D,
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
/// Ok(Self {
@ -54,8 +59,8 @@ pub use self::decoder::DecoderImpl;
/// })
/// }
/// }
/// impl<'de> bincode::BorrowDecode<'de> for Entity {
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de>>(
/// impl<'de, Context> bincode::BorrowDecode<'de, Context> for Entity {
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de, Context = Context>>(
/// decoder: &mut D,
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
/// Ok(Self {
@ -71,20 +76,33 @@ pub use self::decoder::DecoderImpl;
/// To get specific integer types, you can use:
/// ```
/// # struct Foo;
/// # impl bincode::Decode for Foo {
/// # fn decode<D: bincode::de::Decoder>(
/// # impl<Context> bincode::Decode<Context> for Foo {
/// # fn decode<D: bincode::de::Decoder<Context = Context>>(
/// # decoder: &mut D,
/// # ) -> core::result::Result<Self, bincode::error::DecodeError> {
/// let x: u8 = bincode::Decode::decode(decoder)?;
/// let x = <u8 as bincode::Decode>::decode(decoder)?;
/// let x: u8 = bincode::Decode::<Context>::decode(decoder)?;
/// let x = <u8 as bincode::Decode::<Context>>::decode(decoder)?;
/// # Ok(Foo)
/// # }
/// # }
/// # bincode::impl_borrow_decode!(Foo);
/// ```
pub trait Decode: Sized {
///
/// You can use `Context` to require contexts for decoding a type:
/// ```
/// # /// # use bumpalo::Bump;
/// use bincode::de::Decoder;
/// use bincode::error::DecodeError;
/// struct BytesInArena<'a>(bumpalo::collections::Vec<'a, u8>);
/// impl<'a> bincode::Decode<&'a bumpalo::Bump> for BytesInArena<'a> {
/// fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
/// todo!()
/// }
/// # }
/// ```
pub trait Decode<Context>: Sized {
/// Attempt to decode this type with the given [Decode].
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError>;
}
/// Trait that makes a type able to be decoded, akin to serde's `Deserialize` trait.
@ -92,17 +110,33 @@ pub trait Decode: Sized {
/// This trait should be implemented for types that contain borrowed data, like `&str` and `&[u8]`. If your type does not have borrowed data, consider implementing [Decode] instead.
///
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to a type with a lifetime.
pub trait BorrowDecode<'de>: Sized {
pub trait BorrowDecode<'de, Context>: Sized {
/// Attempt to decode this type with the given [BorrowDecode].
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError>;
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError>;
}
/// Helper macro to implement `BorrowDecode` for any type that implements `Decode`.
#[macro_export]
macro_rules! impl_borrow_decode {
($ty:ty $(, $param:ident),*) => {
impl<'de $(, $param)*> $crate::BorrowDecode<'de> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de>>(
($ty:ty $(, $param:tt)*) => {
impl<'de $(, $param)*, __Context> $crate::BorrowDecode<'de, __Context> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = __Context>>(
decoder: &mut D,
) -> core::result::Result<Self, $crate::error::DecodeError> {
$crate::Decode::decode(decoder)
}
}
};
}
/// Helper macro to implement `BorrowDecode` for any type that implements `Decode`.
#[macro_export]
macro_rules! impl_borrow_decode_with_context {
($ty:ty, $context:ty $(, $param:tt)*) => {
impl<'de $(, $param)*> $crate::BorrowDecode<'de, $context> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = $context>>(
decoder: &mut D,
) -> core::result::Result<Self, $crate::error::DecodeError> {
$crate::Decode::decode(decoder)
@ -119,6 +153,20 @@ pub trait Decoder: Sealed {
/// The concrete [Config] type
type C: Config;
/// The decoding context type
type Context;
/// Returns the decoding context
fn context(&mut self) -> &mut Self::Context;
/// Wraps decoder with a context
fn with_context<C>(&mut self, context: C) -> WithContext<Self, C> {
WithContext {
decoder: self,
context,
}
}
/// Returns a mutable reference to the reader
fn reader(&mut self) -> &mut Self::R;
@ -166,8 +214,8 @@ pub trait Decoder: Sealed {
/// # self.0.push(t);
/// # }
/// # }
/// impl<T: Decode> Decode for Container<T> {
/// fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
/// impl<Context, T: Decode<Context>> Decode<Context> for Container<T> {
/// fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
/// let len = u64::decode(decoder)?;
/// let len: usize = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
/// // Make sure we don't allocate too much memory
@ -182,8 +230,8 @@ pub trait Decoder: Sealed {
/// Ok(result)
/// }
/// }
/// impl<'de, T: bincode::BorrowDecode<'de>> bincode::BorrowDecode<'de> for Container<T> {
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de>>(
/// impl<'de, Context, T: bincode::BorrowDecode<'de, Context>> bincode::BorrowDecode<'de, Context> for Container<T> {
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de, Context = Context>>(
/// decoder: &mut D,
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
/// let len = u64::borrow_decode(decoder)?;
@ -223,6 +271,8 @@ where
type C = T::C;
type Context = T::Context;
fn reader(&mut self) -> &mut Self::R {
T::reader(self)
}
@ -240,6 +290,10 @@ where
fn unclaim_bytes_read(&mut self, n: usize) {
T::unclaim_bytes_read(self, n)
}
fn context(&mut self) -> &mut Self::Context {
T::context(self)
}
}
impl<'de, T> BorrowDecoder<'de> for &mut T

View File

@ -63,19 +63,21 @@ pub fn encode_to_vec<E: enc::Encode, C: Config>(val: E, config: C) -> Result<Vec
Ok(encoder.into_writer().inner)
}
impl<T> Decode for BinaryHeap<T>
impl<Context, T> Decode<Context> for BinaryHeap<T>
where
T: Decode + Ord,
T: Decode<Context> + Ord,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Vec::<T>::decode(decoder)?.into())
}
}
impl<'de, T> BorrowDecode<'de> for BinaryHeap<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for BinaryHeap<T>
where
T: BorrowDecode<'de> + Ord,
T: BorrowDecode<'de, Context> + Ord,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
Ok(Vec::<T>::borrow_decode(decoder)?.into())
}
}
@ -94,12 +96,12 @@ where
}
}
impl<K, V> Decode for BTreeMap<K, V>
impl<Context, K, V> Decode<Context> for BTreeMap<K, V>
where
K: Decode + Ord,
V: Decode,
K: Decode<Context> + Ord,
V: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<(K, V)>(len)?;
@ -115,12 +117,14 @@ where
Ok(map)
}
}
impl<'de, K, V> BorrowDecode<'de> for BTreeMap<K, V>
impl<'de, K, V, Context> BorrowDecode<'de, Context> for BTreeMap<K, V>
where
K: BorrowDecode<'de> + Ord,
V: BorrowDecode<'de>,
K: BorrowDecode<'de, Context> + Ord,
V: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<(K, V)>(len)?;
@ -152,11 +156,11 @@ where
}
}
impl<T> Decode for BTreeSet<T>
impl<Context, T> Decode<Context> for BTreeSet<T>
where
T: Decode + Ord,
T: Decode<Context> + Ord,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<T>(len)?;
@ -171,11 +175,13 @@ where
Ok(map)
}
}
impl<'de, T> BorrowDecode<'de> for BTreeSet<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for BTreeSet<T>
where
T: BorrowDecode<'de> + Ord,
T: BorrowDecode<'de, Context> + Ord,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<T>(len)?;
@ -204,19 +210,21 @@ where
}
}
impl<T> Decode for VecDeque<T>
impl<Context, T> Decode<Context> for VecDeque<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Vec::<T>::decode(decoder)?.into())
}
}
impl<'de, T> BorrowDecode<'de> for VecDeque<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for VecDeque<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
Ok(Vec::<T>::borrow_decode(decoder)?.into())
}
}
@ -248,11 +256,11 @@ where
}
}
impl<T> Decode for Vec<T>
impl<Context, T> Decode<Context> for Vec<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
if unty::type_equal::<T, u8>() {
@ -277,11 +285,13 @@ where
}
}
impl<'de, T> BorrowDecode<'de> for Vec<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Vec<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
if unty::type_equal::<T, u8>() {
@ -326,8 +336,8 @@ where
}
}
impl Decode for String {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for String {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let bytes = Vec::<u8>::decode(decoder)?;
String::from_utf8(bytes).map_err(|e| DecodeError::Utf8 {
inner: e.utf8_error(),
@ -336,7 +346,7 @@ impl Decode for String {
}
impl_borrow_decode!(String);
impl Decode for Box<str> {
impl<Context> Decode<Context> for Box<str> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
String::decode(decoder).map(String::into_boxed_str)
}
@ -349,20 +359,22 @@ impl Encode for String {
}
}
impl<T> Decode for Box<T>
impl<Context, T> Decode<Context> for Box<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(Box::new(t))
}
}
impl<'de, T> BorrowDecode<'de> for Box<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Box<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(Box::new(t))
}
@ -377,42 +389,46 @@ where
}
}
impl<T> Decode for Box<[T]>
impl<Context, T> Decode<Context> for Box<[T]>
where
T: Decode + 'static,
T: Decode<Context> + 'static,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let vec = Vec::decode(decoder)?;
Ok(vec.into_boxed_slice())
}
}
impl<'de, T> BorrowDecode<'de> for Box<[T]>
impl<'de, T, Context> BorrowDecode<'de, Context> for Box<[T]>
where
T: BorrowDecode<'de> + 'de,
T: BorrowDecode<'de, Context> + 'de,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let vec = Vec::borrow_decode(decoder)?;
Ok(vec.into_boxed_slice())
}
}
impl<T> Decode for Cow<'_, T>
impl<Context, T> Decode<Context> for Cow<'_, T>
where
T: ToOwned + ?Sized,
<T as ToOwned>::Owned: Decode,
<T as ToOwned>::Owned: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = <T as ToOwned>::Owned::decode(decoder)?;
Ok(Cow::Owned(t))
}
}
impl<'cow, T> BorrowDecode<'cow> for Cow<'cow, T>
impl<'cow, T, Context> BorrowDecode<'cow, Context> for Cow<'cow, T>
where
T: ToOwned + ?Sized,
&'cow T: BorrowDecode<'cow>,
&'cow T: BorrowDecode<'cow, Context>,
{
fn borrow_decode<D: BorrowDecoder<'cow>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'cow, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = <&T>::borrow_decode(decoder)?;
Ok(Cow::Borrowed(t))
}
@ -441,35 +457,39 @@ fn test_cow_round_trip() {
assert_eq!(start, end);
}
impl<T> Decode for Rc<T>
impl<Context, T> Decode<Context> for Rc<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(Rc::new(t))
}
}
impl Decode for Rc<str> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for Rc<str> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let decoded = String::decode(decoder)?;
Ok(decoded.into())
}
}
impl<'de, T> BorrowDecode<'de> for Rc<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Rc<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(Rc::new(t))
}
}
impl<'de> BorrowDecode<'de> for Rc<str> {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'de, Context> BorrowDecode<'de, Context> for Rc<str> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let decoded = String::decode(decoder)?;
Ok(decoded.into())
}
@ -484,59 +504,65 @@ where
}
}
impl<T> Decode for Rc<[T]>
impl<Context, T> Decode<Context> for Rc<[T]>
where
T: Decode + 'static,
T: Decode<Context> + 'static,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let vec = Vec::decode(decoder)?;
Ok(vec.into())
}
}
impl<'de, T> BorrowDecode<'de> for Rc<[T]>
impl<'de, T, Context> BorrowDecode<'de, Context> for Rc<[T]>
where
T: BorrowDecode<'de> + 'de,
T: BorrowDecode<'de, Context> + 'de,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let vec = Vec::borrow_decode(decoder)?;
Ok(vec.into())
}
}
#[cfg(target_has_atomic = "ptr")]
impl<T> Decode for Arc<T>
impl<Context, T> Decode<Context> for Arc<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(Arc::new(t))
}
}
#[cfg(target_has_atomic = "ptr")]
impl Decode for Arc<str> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for Arc<str> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let decoded = String::decode(decoder)?;
Ok(decoded.into())
}
}
#[cfg(target_has_atomic = "ptr")]
impl<'de, T> BorrowDecode<'de> for Arc<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Arc<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(Arc::new(t))
}
}
#[cfg(target_has_atomic = "ptr")]
impl<'de> BorrowDecode<'de> for Arc<str> {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'de, Context> BorrowDecode<'de, Context> for Arc<str> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let decoded = String::decode(decoder)?;
Ok(decoded.into())
}
@ -553,22 +579,24 @@ where
}
#[cfg(target_has_atomic = "ptr")]
impl<T> Decode for Arc<[T]>
impl<Context, T> Decode<Context> for Arc<[T]>
where
T: Decode + 'static,
T: Decode<Context> + 'static,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let vec = Vec::decode(decoder)?;
Ok(vec.into())
}
}
#[cfg(target_has_atomic = "ptr")]
impl<'de, T> BorrowDecode<'de> for Arc<[T]>
impl<'de, T, Context> BorrowDecode<'de, Context> for Arc<[T]>
where
T: BorrowDecode<'de> + 'de,
T: BorrowDecode<'de, Context> + 'de,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let vec = Vec::borrow_decode(decoder)?;
Ok(vec.into())
}

View File

@ -23,12 +23,31 @@ use std::{
///
/// [config]: config/index.html
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn decode_from_std_read<D: Decode, C: Config, R: std::io::Read>(
pub fn decode_from_std_read<D: Decode<()>, C: Config, R: std::io::Read>(
src: &mut R,
config: C,
) -> Result<D, DecodeError> {
decode_from_std_read_with_context(src, config, ())
}
/// Decode type `D` from the given reader with the given `Config` and `Context`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`.
///
/// See the [config] module for more information about config options.
///
/// [config]: config/index.html
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn decode_from_std_read_with_context<
Context,
D: Decode<Context>,
C: Config,
R: std::io::Read,
>(
src: &mut R,
config: C,
context: Context,
) -> Result<D, DecodeError> {
let reader = IoReader::new(src);
let mut decoder = DecoderImpl::<_, C>::new(reader, config);
let mut decoder = DecoderImpl::<_, C, Context>::new(reader, config, context);
D::decode(&mut decoder)
}
@ -140,8 +159,8 @@ impl Encode for CString {
}
}
impl Decode for CString {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for CString {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let vec = std::vec::Vec::decode(decoder)?;
CString::new(vec).map_err(|inner| DecodeError::CStringNulError {
position: inner.nul_position(),
@ -162,20 +181,22 @@ where
}
}
impl<T> Decode for Mutex<T>
impl<Context, T> Decode<Context> for Mutex<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(Mutex::new(t))
}
}
impl<'de, T> BorrowDecode<'de> for Mutex<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for Mutex<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(Mutex::new(t))
}
@ -193,20 +214,22 @@ where
}
}
impl<T> Decode for RwLock<T>
impl<Context, T> Decode<Context> for RwLock<T>
where
T: Decode,
T: Decode<Context>,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let t = T::decode(decoder)?;
Ok(RwLock::new(t))
}
}
impl<'de, T> BorrowDecode<'de> for RwLock<T>
impl<'de, T, Context> BorrowDecode<'de, Context> for RwLock<T>
where
T: BorrowDecode<'de>,
T: BorrowDecode<'de, Context>,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let t = T::borrow_decode(decoder)?;
Ok(RwLock::new(t))
}
@ -224,8 +247,8 @@ impl Encode for SystemTime {
}
}
impl Decode for SystemTime {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for SystemTime {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let duration = Duration::decode(decoder)?;
match SystemTime::UNIX_EPOCH.checked_add(duration) {
Some(t) => Ok(t),
@ -244,8 +267,10 @@ impl Encode for &'_ Path {
}
}
impl<'de> BorrowDecode<'de> for &'de Path {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<'de, Context> BorrowDecode<'de, Context> for &'de Path {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let str = <&'de str>::borrow_decode(decoder)?;
Ok(Path::new(str))
}
@ -257,8 +282,8 @@ impl Encode for PathBuf {
}
}
impl Decode for PathBuf {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for PathBuf {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let string = std::string::String::decode(decoder)?;
Ok(string.into())
}
@ -280,8 +305,8 @@ impl Encode for IpAddr {
}
}
impl Decode for IpAddr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for IpAddr {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
match u32::decode(decoder)? {
0 => Ok(IpAddr::V4(Ipv4Addr::decode(decoder)?)),
1 => Ok(IpAddr::V6(Ipv6Addr::decode(decoder)?)),
@ -301,8 +326,8 @@ impl Encode for Ipv4Addr {
}
}
impl Decode for Ipv4Addr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for Ipv4Addr {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let mut buff = [0u8; 4];
decoder.reader().read(&mut buff)?;
Ok(Self::from(buff))
@ -316,8 +341,8 @@ impl Encode for Ipv6Addr {
}
}
impl Decode for Ipv6Addr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for Ipv6Addr {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let mut buff = [0u8; 16];
decoder.reader().read(&mut buff)?;
Ok(Self::from(buff))
@ -340,8 +365,8 @@ impl Encode for SocketAddr {
}
}
impl Decode for SocketAddr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for SocketAddr {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
match u32::decode(decoder)? {
0 => Ok(SocketAddr::V4(SocketAddrV4::decode(decoder)?)),
1 => Ok(SocketAddr::V6(SocketAddrV6::decode(decoder)?)),
@ -362,8 +387,8 @@ impl Encode for SocketAddrV4 {
}
}
impl Decode for SocketAddrV4 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for SocketAddrV4 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let ip = Ipv4Addr::decode(decoder)?;
let port = u16::decode(decoder)?;
Ok(Self::new(ip, port))
@ -378,8 +403,8 @@ impl Encode for SocketAddrV6 {
}
}
impl Decode for SocketAddrV6 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
impl<Context> Decode<Context> for SocketAddrV6 {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let ip = Ipv6Addr::decode(decoder)?;
let port = u16::decode(decoder)?;
Ok(Self::new(ip, port, 0, 0))
@ -421,13 +446,13 @@ where
}
}
impl<K, V, S> Decode for HashMap<K, V, S>
impl<Context, K, V, S> Decode<Context> for HashMap<K, V, S>
where
K: Decode + Eq + std::hash::Hash,
V: Decode,
K: Decode<Context> + Eq + std::hash::Hash,
V: Decode<Context>,
S: std::hash::BuildHasher + Default,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<(K, V)>(len)?;
@ -444,13 +469,15 @@ where
Ok(map)
}
}
impl<'de, K, V, S> BorrowDecode<'de> for HashMap<K, V, S>
impl<'de, K, V, S, Context> BorrowDecode<'de, Context> for HashMap<K, V, S>
where
K: BorrowDecode<'de> + Eq + std::hash::Hash,
V: BorrowDecode<'de>,
K: BorrowDecode<'de, Context> + Eq + std::hash::Hash,
V: BorrowDecode<'de, Context>,
S: std::hash::BuildHasher + Default,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<(K, V)>(len)?;
@ -468,12 +495,12 @@ where
}
}
impl<T, S> Decode for HashSet<T, S>
impl<Context, T, S> Decode<Context> for HashSet<T, S>
where
T: Decode + Eq + Hash,
T: Decode<Context> + Eq + Hash,
S: std::hash::BuildHasher + Default,
{
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<T>(len)?;
@ -490,12 +517,14 @@ where
}
}
impl<'de, T, S> BorrowDecode<'de> for HashSet<T, S>
impl<'de, T, S, Context> BorrowDecode<'de, Context> for HashSet<T, S>
where
T: BorrowDecode<'de> + Eq + Hash,
T: BorrowDecode<'de, Context> + Eq + Hash,
S: std::hash::BuildHasher + Default,
{
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<T>(len)?;

View File

@ -25,17 +25,18 @@ impl<'de, DE: BorrowDecoder<'de>> BorrowedSerdeDecoder<'de, DE> {
}
}
impl<'de, C: Config> BorrowedSerdeDecoder<'de, DecoderImpl<SliceReader<'de>, C>> {
impl<'de, C: Config, Context> BorrowedSerdeDecoder<'de, DecoderImpl<SliceReader<'de>, C, Context>> {
/// Creates the decoder from a borrowed slice.
pub fn from_slice(
slice: &'de [u8],
config: C,
) -> BorrowedSerdeDecoder<'de, DecoderImpl<SliceReader<'de>, C>>
context: Context,
) -> BorrowedSerdeDecoder<'de, DecoderImpl<SliceReader<'de>, C, Context>>
where
C: Config,
{
let reader = SliceReader::new(slice);
let decoder = DecoderImpl::new(reader, config);
let decoder = DecoderImpl::new(reader, config, context);
Self {
de: decoder,
pd: PhantomData,
@ -55,7 +56,7 @@ where
C: Config,
{
let mut serde_decoder =
BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C, ()>>::from_slice(slice, config, ());
let result = D::deserialize(serde_decoder.as_deserializer())?;
let bytes_read = slice.len() - serde_decoder.de.borrow_reader().slice.len();
Ok((result, bytes_read))
@ -72,7 +73,7 @@ where
C: Config,
{
let mut serde_decoder =
BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C, ()>>::from_slice(slice, config, ());
let result = seed.deserialize(serde_decoder.as_deserializer())?;
let bytes_read = slice.len() - serde_decoder.de.borrow_reader().slice.len();
Ok((result, bytes_read))

View File

@ -24,28 +24,28 @@ impl<DE: Decoder> OwnedSerdeDecoder<DE> {
}
#[cfg(feature = "std")]
impl<'r, C: Config, R: std::io::Read> OwnedSerdeDecoder<DecoderImpl<IoReader<&'r mut R>, C>> {
impl<'r, C: Config, R: std::io::Read> OwnedSerdeDecoder<DecoderImpl<IoReader<&'r mut R>, C, ()>> {
/// Creates the decoder from an `std::io::Read` implementor.
pub fn from_std_read(
src: &'r mut R,
config: C,
) -> OwnedSerdeDecoder<DecoderImpl<IoReader<&'r mut R>, C>>
) -> OwnedSerdeDecoder<DecoderImpl<IoReader<&'r mut R>, C, ()>>
where
C: Config,
{
let reader = IoReader::new(src);
let decoder = DecoderImpl::new(reader, config);
let decoder = DecoderImpl::new(reader, config, ());
Self { de: decoder }
}
}
impl<C: Config, R: Reader> OwnedSerdeDecoder<DecoderImpl<R, C>> {
impl<C: Config, R: Reader> OwnedSerdeDecoder<DecoderImpl<R, C, ()>> {
/// Creates the decoder from a [`Reader`] implementor.
pub fn from_reader(reader: R, config: C) -> OwnedSerdeDecoder<DecoderImpl<R, C>>
pub fn from_reader(reader: R, config: C) -> OwnedSerdeDecoder<DecoderImpl<R, C, ()>>
where
C: Config,
{
let decoder = DecoderImpl::new(reader, config);
let decoder = DecoderImpl::new(reader, config, ());
Self { de: decoder }
}
}
@ -78,7 +78,7 @@ pub fn decode_from_std_read<'r, D: DeserializeOwned, C: Config, R: std::io::Read
config: C,
) -> Result<D, DecodeError> {
let mut serde_decoder =
OwnedSerdeDecoder::<DecoderImpl<IoReader<&'r mut R>, C>>::from_std_read(src, config);
OwnedSerdeDecoder::<DecoderImpl<IoReader<&'r mut R>, C, ()>>::from_std_read(src, config);
D::deserialize(serde_decoder.as_deserializer())
}
@ -91,7 +91,7 @@ pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
reader: R,
config: C,
) -> Result<D, DecodeError> {
let mut serde_decoder = OwnedSerdeDecoder::<DecoderImpl<R, C>>::from_reader(reader, config);
let mut serde_decoder = OwnedSerdeDecoder::<DecoderImpl<R, C, ()>>::from_reader(reader, config);
D::deserialize(serde_decoder.as_deserializer())
}

View File

@ -193,7 +193,7 @@ impl serde::ser::Error for crate::error::EncodeError {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Compat<T>(pub T);
impl<T> crate::Decode for Compat<T>
impl<Context, T> crate::Decode<Context> for Compat<T>
where
T: serde::de::DeserializeOwned,
{
@ -202,7 +202,7 @@ where
T::deserialize(serde_decoder).map(Compat)
}
}
impl<'de, T> crate::BorrowDecode<'de> for Compat<T>
impl<'de, T, Context> crate::BorrowDecode<'de, Context> for Compat<T>
where
T: serde::de::DeserializeOwned,
{
@ -255,7 +255,7 @@ where
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct BorrowCompat<T>(pub T);
impl<'de, T> crate::de::BorrowDecode<'de> for BorrowCompat<T>
impl<'de, T, Context> crate::de::BorrowDecode<'de, Context> for BorrowCompat<T>
where
T: serde::de::Deserialize<'de>,
{

View File

@ -145,12 +145,27 @@ pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
pub fn decode_from_slice<D: de::Decode, C: Config>(
pub fn decode_from_slice<D: de::Decode<()>, C: Config>(
src: &[u8],
config: C,
) -> Result<(D, usize), error::DecodeError> {
decode_from_slice_with_context(src, config, ())
}
/// Attempt to decode a given type `D` from the given slice with `Context`. Returns the decoded output and the amount of bytes read.
///
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
///
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
pub fn decode_from_slice_with_context<Context, D: de::Decode<Context>, C: Config>(
src: &[u8],
config: C,
context: Context,
) -> Result<(D, usize), error::DecodeError> {
let reader = de::read::SliceReader::new(src);
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
let result = D::decode(&mut decoder)?;
let bytes_read = src.len() - decoder.reader().slice.len();
Ok((result, bytes_read))
@ -161,12 +176,30 @@ pub fn decode_from_slice<D: de::Decode, C: Config>(
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
pub fn borrow_decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>(
pub fn borrow_decode_from_slice<'a, D: de::BorrowDecode<'a, ()>, C: Config>(
src: &'a [u8],
config: C,
) -> Result<(D, usize), error::DecodeError> {
borrow_decode_from_slice_with_context(src, config, ())
}
/// Attempt to decode a given type `D` from the given slice with `Context`. Returns the decoded output and the amount of bytes read.
///
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
pub fn borrow_decode_from_slice_with_context<
'a,
Context,
D: de::BorrowDecode<'a, Context>,
C: Config,
>(
src: &'a [u8],
config: C,
context: Context,
) -> Result<(D, usize), error::DecodeError> {
let reader = de::read::SliceReader::new(src);
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
let mut decoder = de::DecoderImpl::<_, C, Context>::new(reader, config, context);
let result = D::borrow_decode(&mut decoder)?;
let bytes_read = src.len() - decoder.reader().slice.len();
Ok((result, bytes_read))
@ -177,11 +210,11 @@ pub fn borrow_decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>(
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
pub fn decode_from_reader<D: de::Decode, R: Reader, C: Config>(
pub fn decode_from_reader<D: de::Decode<()>, R: Reader, C: Config>(
reader: R,
config: C,
) -> Result<D, error::DecodeError> {
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
let mut decoder = de::DecoderImpl::<_, C, ()>::new(reader, config, ());
D::decode(&mut decoder)
}

View File

@ -29,7 +29,7 @@ impl bincode::Encode for Foo {
}
}
impl bincode::Decode for Foo {
impl<Context> bincode::Decode<Context> for Foo {
fn decode<D: bincode::de::Decoder>(
decoder: &mut D,
) -> Result<Self, bincode::error::DecodeError> {
@ -145,7 +145,9 @@ fn test_container_limits() {
bincode::encode_to_vec(DECODE_LIMIT as u64, bincode::config::standard()).unwrap(),
];
fn validate_fail<T: Decode + for<'de> BorrowDecode<'de> + core::fmt::Debug>(slice: &[u8]) {
fn validate_fail<T: Decode<()> + for<'de> BorrowDecode<'de, ()> + core::fmt::Debug>(
slice: &[u8],
) {
let result = bincode::decode_from_slice::<T, _>(
slice,
bincode::config::standard().with_limit::<DECODE_LIMIT>(),

105
tests/context.rs Normal file
View File

@ -0,0 +1,105 @@
#![cfg(all(feature = "alloc", feature = "derive"))]
use bincode::{
config, de::BorrowDecoder, decode_from_slice, decode_from_slice_with_context, encode_to_vec,
error::DecodeError, BorrowDecode, Decode, Encode,
};
use bumpalo::{collections::Vec, vec, Bump};
#[derive(PartialEq, Eq, Debug)]
struct CodableVec<'bump, T: 'bump>(Vec<'bump, T>);
impl<'bump, T: Encode> Encode for CodableVec<'bump, T> {
fn encode<E: bincode::enc::Encoder>(
&self,
encoder: &mut E,
) -> Result<(), bincode::error::EncodeError> {
self.0.as_slice().encode(encoder)
}
}
impl<'bump, T: Decode<&'bump Bump>> Decode<&'bump Bump> for CodableVec<'bump, T> {
fn decode<D: bincode::de::Decoder<Context = &'bump Bump>>(
decoder: &mut D,
) -> Result<Self, bincode::error::DecodeError> {
let len = u64::decode(decoder)?;
let len = usize::try_from(len).map_err(|_| DecodeError::OutsideUsizeRange(len))?;
decoder.claim_container_read::<T>(len)?;
let mut vec = Vec::with_capacity_in(len, decoder.context());
for _ in 0..len {
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
vec.push(T::decode(decoder)?);
}
Ok(Self(vec))
}
}
impl<'de, 'bump, T: BorrowDecode<'de, &'bump Bump>> BorrowDecode<'de, &'bump Bump>
for CodableVec<'bump, T>
{
fn borrow_decode<D: BorrowDecoder<'de, Context = &'bump Bump>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
let len = u64::decode(decoder)?;
let len = usize::try_from(len).map_err(|_| DecodeError::OutsideUsizeRange(len))?;
decoder.claim_container_read::<T>(len)?;
let mut vec = Vec::with_capacity_in(len, decoder.context());
for _ in 0..len {
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
vec.push(T::borrow_decode(decoder)?);
}
Ok(Self(vec))
}
}
#[derive(Encode, Decode, PartialEq, Eq, Debug)]
#[bincode(decode_context = "&'bump Bump")]
struct Container<'bump> {
vec: CodableVec<'bump, u32>,
}
#[derive(Encode, Decode, PartialEq, Eq, Debug)]
#[bincode(decode_context = "&'bump Bump")]
enum _EnumContainer<'bump> {
Vec(CodableVec<'bump, u32>),
}
#[ouroboros::self_referencing]
struct SelfReferencing {
bump: Bump,
#[borrows(bump)]
#[not_covariant]
container: Container<'this>,
}
impl<Context> Decode<Context> for SelfReferencing {
fn decode<D: bincode::de::Decoder<Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError> {
SelfReferencing::try_new(Bump::new(), |bump| {
Container::decode(&mut decoder.with_context(bump))
})
}
}
#[test]
fn decode_with_context() {
let config = config::standard();
let bump = Bump::new();
let container = Container {
vec: CodableVec(vec![in &bump; 1, 2, 3]),
};
let bytes = encode_to_vec(&container, config).unwrap();
let (decoded_container, _) =
decode_from_slice_with_context::<_, Container, _>(&bytes, config, &bump).unwrap();
assert_eq!(container, decoded_container);
let self_referencing: SelfReferencing = decode_from_slice(&bytes, config).unwrap().0;
self_referencing.with_container(|c| assert_eq!(&container, c))
}

View File

@ -28,11 +28,11 @@ pub struct Test2<T> {
b: u32,
c: u32,
}
impl<T> ::bincode::Decode for Test2<T>
impl<T, Context> ::bincode::Decode<Context> for Test2<T>
where
T: ::bincode::Decode,
T: ::bincode::Decode<Context>,
{
fn decode<D: ::bincode::de::Decoder>(
fn decode<D: ::bincode::de::Decoder<Context = Context>>(
decoder: &mut D,
) -> core::result::Result<Self, ::bincode::error::DecodeError> {
Ok(Self {
@ -42,11 +42,11 @@ where
})
}
}
impl<'__de, T> ::bincode::BorrowDecode<'__de> for Test2<T>
impl<'__de, T, Context> ::bincode::BorrowDecode<'__de, Context> for Test2<T>
where
T: ::bincode::BorrowDecode<'__de> + '__de,
T: ::bincode::BorrowDecode<'__de, Context> + '__de,
{
fn borrow_decode<D: ::bincode::de::BorrowDecoder<'__de>>(
fn borrow_decode<D: ::bincode::de::BorrowDecoder<'__de, Context = Context>>(
decoder: &mut D,
) -> core::result::Result<Self, ::bincode::error::DecodeError> {
Ok(Self {

View File

@ -8,15 +8,19 @@ use std::string::String;
#[derive(Decode, Encode, PartialEq, Debug)]
#[bincode(
borrow_decode_bounds = "&'__de U<'a, A>: ::bincode::de::BorrowDecode<'__de> + '__de, '__de: 'a"
decode_context = "()",
borrow_decode_bounds = "&'__de U<'a, A>: ::bincode::de::BorrowDecode<'__de, ()> + '__de, '__de: 'a"
)]
struct T<'a, A: Clone + Encode + Decode> {
struct T<'a, A: Clone + Encode + Decode<()>> {
t: Cow<'a, U<'a, A>>,
}
#[derive(Clone, Decode, Encode, PartialEq, Debug)]
#[bincode(borrow_decode_bounds = "&'__de A: ::bincode::de::BorrowDecode<'__de> + '__de, '__de: 'a")]
struct U<'a, A: Clone + Encode + Decode> {
#[bincode(
decode_context = "()",
borrow_decode_bounds = "&'__de A: ::bincode::de::BorrowDecode<'__de, ()> + '__de, '__de: 'a"
)]
struct U<'a, A: Clone + Encode + Decode<()>> {
u: Cow<'a, A>,
}

View File

@ -7,7 +7,7 @@ pub struct A;
#[derive(Encode, Decode, Clone)]
pub struct B<T>
where
T: Clone + Encode + Decode,
T: Clone + Encode + Decode<()>,
{
pub t: T,
}
@ -15,7 +15,7 @@ where
#[derive(Encode, Decode)]
pub struct MyStruct<T>
where
T: Clone + Encode + Decode,
T: Clone + Encode + Decode<()>,
{
pub a: A,
pub b: B<T>,

View File

@ -2,7 +2,6 @@
extern crate alloc;
use alloc::string::String;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, bincode::Encode, bincode::Decode)]
@ -174,7 +173,7 @@ mod derive {
fn test_serde_derive() {
fn test_encode_decode<T>(start: T, expected_len: usize)
where
T: bincode::Encode + bincode::Decode + PartialEq + core::fmt::Debug,
T: bincode::Encode + bincode::Decode<()> + PartialEq + core::fmt::Debug,
{
let mut slice = [0u8; 100];
let len = bincode::encode_into_slice(&start, &mut slice, bincode::config::standard())

View File

@ -31,7 +31,7 @@ impl bincode::Encode for Foo {
}
}
impl bincode::Decode for Foo {
impl<Context> bincode::Decode<Context> for Foo {
fn decode<D: bincode::de::Decoder>(
decoder: &mut D,
) -> Result<Self, bincode::error::DecodeError> {

View File

@ -128,13 +128,18 @@ where
#[cfg(feature = "serde")]
pub trait TheSameTrait:
bincode::Encode + bincode::Decode + serde::de::DeserializeOwned + serde::Serialize + Debug + 'static
bincode::Encode
+ bincode::Decode<()>
+ serde::de::DeserializeOwned
+ serde::Serialize
+ Debug
+ 'static
{
}
#[cfg(feature = "serde")]
impl<T> TheSameTrait for T where
T: bincode::Encode
+ bincode::Decode
+ bincode::Decode<()>
+ serde::de::DeserializeOwned
+ serde::Serialize
+ Debug
@ -143,9 +148,9 @@ impl<T> TheSameTrait for T where
}
#[cfg(not(feature = "serde"))]
pub trait TheSameTrait: bincode::Encode + bincode::Decode + Debug + 'static {}
pub trait TheSameTrait: bincode::Encode + bincode::Decode<()> + Debug + 'static {}
#[cfg(not(feature = "serde"))]
impl<T> TheSameTrait for T where T: bincode::Encode + bincode::Decode + Debug + 'static {}
impl<T> TheSameTrait for T where T: bincode::Encode + bincode::Decode<()> + Debug + 'static {}
#[allow(dead_code)] // This is not used in every test
pub fn the_same<V: TheSameTrait + PartialEq>(element: V) {