mirror of https://git.sr.ht/~stygianentity/bincode
Rewrite: seperated Decode and BorrowDecode (#526)
* Rewrite: seperated Decode and BorrowDecode * Fixed cargo.toml issues * Fixed clippy warning * Removed the `impl_tuples` macro call with manually exported code * Replaced the generated code in `impl_tuples` with the macro instead * Implemented BorrowDecode for Box<[T]> * Added a test to see if zoxide can be ported to bincode 2 * Added a test for Arc<str> * Made several `Encode` implementations require `T: ?Sized` * Implemented Decode for Arc<str> * Added BlockedTODO links to commented out code * Fixed clippy and lint issues * Updated virtue dependency in fuzz lockfile
This commit is contained in:
parent
f979383adb
commit
86e03aeda7
|
|
@ -16,4 +16,4 @@ description = "Implementation of #[derive(Encode, Decode)] for bincode"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
virtue = "0.0.7"
|
virtue = "0.0.8"
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,20 @@ use virtue::utils::{parse_tagged_attribute, ParsedAttribute};
|
||||||
|
|
||||||
pub struct ContainerAttributes {
|
pub struct ContainerAttributes {
|
||||||
pub crate_name: String,
|
pub crate_name: String,
|
||||||
|
pub bounds: Option<(String, Literal)>,
|
||||||
|
pub decode_bounds: Option<(String, Literal)>,
|
||||||
|
pub borrow_decode_bounds: Option<(String, Literal)>,
|
||||||
|
pub encode_bounds: Option<(String, Literal)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ContainerAttributes {
|
impl Default for ContainerAttributes {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
crate_name: "::bincode".to_string(),
|
crate_name: "::bincode".to_string(),
|
||||||
|
bounds: None,
|
||||||
|
decode_bounds: None,
|
||||||
|
encode_bounds: None,
|
||||||
|
borrow_decode_bounds: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,6 +38,44 @@ impl FromAttribute for ContainerAttributes {
|
||||||
return Err(Error::custom_at("Should be a literal str", val.span()));
|
return Err(Error::custom_at("Should be a literal str", val.span()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ParsedAttribute::Property(key, val) if key.to_string() == "bounds" => {
|
||||||
|
let val_string = val.to_string();
|
||||||
|
if val_string.starts_with('"') && val_string.ends_with('"') {
|
||||||
|
result.bounds =
|
||||||
|
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() == "decode_bounds" => {
|
||||||
|
let val_string = val.to_string();
|
||||||
|
if val_string.starts_with('"') && val_string.ends_with('"') {
|
||||||
|
result.decode_bounds =
|
||||||
|
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('"') {
|
||||||
|
result.encode_bounds =
|
||||||
|
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() == "borrow_decode_bounds" =>
|
||||||
|
{
|
||||||
|
let val_string = val.to_string();
|
||||||
|
if val_string.starts_with('"') && val_string.ends_with('"') {
|
||||||
|
result.borrow_decode_bounds =
|
||||||
|
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::Tag(i) => {
|
ParsedAttribute::Tag(i) => {
|
||||||
return Err(Error::custom_at("Unknown field attribute", i.span()))
|
return Err(Error::custom_at("Unknown field attribute", i.span()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,22 @@ impl DeriveEnum {
|
||||||
generator
|
generator
|
||||||
.impl_for(format!("{}::Encode", crate_name))
|
.impl_for(format!("{}::Encode", crate_name))
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) =
|
||||||
|
(self.attributes.encode_bounds.as_ref()).or(self.attributes.bounds.as_ref())
|
||||||
|
{
|
||||||
|
where_constraints.clear();
|
||||||
where_constraints
|
where_constraints
|
||||||
.push_constraint(g, format!("{}::Encode", crate_name))
|
.push_parsed_constraint(bounds)
|
||||||
.unwrap();
|
.map_err(|e| e.with_span(lit.span()))?;
|
||||||
|
} else {
|
||||||
|
for g in generics.iter_generics() {
|
||||||
|
where_constraints
|
||||||
|
.push_constraint(g, format!("{}::Encode", crate_name))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("encode")
|
.generate_fn("encode")
|
||||||
.with_generic_deps("E", [format!("{}::enc::Encoder", crate_name)])
|
.with_generic_deps("E", [format!("{}::enc::Encoder", crate_name)])
|
||||||
.with_self_arg(FnSelfArg::RefSelf)
|
.with_self_arg(FnSelfArg::RefSelf)
|
||||||
|
|
@ -206,7 +216,7 @@ impl DeriveEnum {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_decode(&self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_decode(self, generator: &mut Generator) -> Result<()> {
|
||||||
let crate_name = self.attributes.crate_name.as_str();
|
let crate_name = self.attributes.crate_name.as_str();
|
||||||
|
|
||||||
// Remember to keep this mostly in sync with generate_borrow_decode
|
// Remember to keep this mostly in sync with generate_borrow_decode
|
||||||
|
|
@ -216,10 +226,16 @@ impl DeriveEnum {
|
||||||
generator
|
generator
|
||||||
.impl_for(format!("{}::Decode", crate_name))
|
.impl_for(format!("{}::Decode", crate_name))
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) = (self.attributes.decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
|
||||||
where_constraints.push_constraint(g, format!("{}::Decode", crate_name)).unwrap();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("decode")
|
.generate_fn("decode")
|
||||||
.with_generic_deps("D", [format!("{}::de::Decoder", crate_name)])
|
.with_generic_deps("D", [format!("{}::de::Decoder", crate_name)])
|
||||||
.with_arg("decoder", "&mut D")
|
.with_arg("decoder", "&mut D")
|
||||||
|
|
@ -293,6 +309,7 @@ impl DeriveEnum {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
self.generate_borrow_decode(generator)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,10 +321,16 @@ impl DeriveEnum {
|
||||||
|
|
||||||
generator.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
|
generator.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) = (self.attributes.borrow_decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
|
||||||
where_constraints.push_constraint(g, format!("{}::enc::BorrowDecode", crate_name)).unwrap();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("borrow_decode")
|
.generate_fn("borrow_decode")
|
||||||
.with_generic_deps("D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
|
.with_generic_deps("D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
|
||||||
.with_arg("decoder", "&mut D")
|
.with_arg("decoder", "&mut D")
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,26 @@ pub(crate) struct DeriveStruct {
|
||||||
|
|
||||||
impl DeriveStruct {
|
impl DeriveStruct {
|
||||||
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
||||||
let DeriveStruct { fields, attributes } = self;
|
let crate_name = &self.attributes.crate_name;
|
||||||
let crate_name = attributes.crate_name;
|
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for(&format!("{}::Encode", crate_name))
|
.impl_for(&format!("{}::Encode", crate_name))
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) =
|
||||||
|
(self.attributes.encode_bounds.as_ref()).or(self.attributes.bounds.as_ref())
|
||||||
|
{
|
||||||
|
where_constraints.clear();
|
||||||
where_constraints
|
where_constraints
|
||||||
.push_constraint(g, format!("{}::Encode", crate_name))
|
.push_parsed_constraint(bounds)
|
||||||
.unwrap();
|
.map_err(|e| e.with_span(lit.span()))?;
|
||||||
|
} else {
|
||||||
|
for g in generics.iter_generics() {
|
||||||
|
where_constraints
|
||||||
|
.push_constraint(g, format!("{}::Encode", crate_name))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("encode")
|
.generate_fn("encode")
|
||||||
.with_generic_deps("E", [format!("{}::enc::Encoder", crate_name)])
|
.with_generic_deps("E", [format!("{}::enc::Encoder", crate_name)])
|
||||||
.with_self_arg(virtue::generate::FnSelfArg::RefSelf)
|
.with_self_arg(virtue::generate::FnSelfArg::RefSelf)
|
||||||
|
|
@ -31,7 +39,7 @@ impl DeriveStruct {
|
||||||
crate_name
|
crate_name
|
||||||
))
|
))
|
||||||
.body(|fn_body| {
|
.body(|fn_body| {
|
||||||
for field in fields.names() {
|
for field in self.fields.names() {
|
||||||
let attributes = field
|
let attributes = field
|
||||||
.attributes()
|
.attributes()
|
||||||
.get_attribute::<FieldAttributes>()?
|
.get_attribute::<FieldAttributes>()?
|
||||||
|
|
@ -56,16 +64,21 @@ impl DeriveStruct {
|
||||||
|
|
||||||
pub fn generate_decode(self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_decode(self, generator: &mut Generator) -> Result<()> {
|
||||||
// Remember to keep this mostly in sync with generate_borrow_decode
|
// Remember to keep this mostly in sync with generate_borrow_decode
|
||||||
let DeriveStruct { fields, attributes } = self;
|
let crate_name = &self.attributes.crate_name;
|
||||||
let crate_name = attributes.crate_name;
|
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for(format!("{}::Decode", crate_name))
|
.impl_for(format!("{}::Decode", crate_name))
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) = (self.attributes.decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
|
||||||
where_constraints.push_constraint(g, format!("{}::Decode", crate_name)).unwrap();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("decode")
|
.generate_fn("decode")
|
||||||
.with_generic_deps("D", [format!("{}::de::Decoder", crate_name)])
|
.with_generic_deps("D", [format!("{}::de::Decoder", crate_name)])
|
||||||
.with_arg("decoder", "&mut D")
|
.with_arg("decoder", "&mut D")
|
||||||
|
|
@ -82,7 +95,7 @@ impl DeriveStruct {
|
||||||
// b: bincode::Decode::decode(decoder)?,
|
// b: bincode::Decode::decode(decoder)?,
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
for field in fields.names() {
|
for field in &self.fields.names() {
|
||||||
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
|
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
|
||||||
if attributes.with_serde {
|
if attributes.with_serde {
|
||||||
struct_body
|
struct_body
|
||||||
|
|
@ -106,21 +119,27 @@ impl DeriveStruct {
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
self.generate_borrow_decode(generator)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_borrow_decode(self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_borrow_decode(self, generator: &mut Generator) -> Result<()> {
|
||||||
// Remember to keep this mostly in sync with generate_decode
|
// Remember to keep this mostly in sync with generate_decode
|
||||||
let DeriveStruct { fields, attributes } = self;
|
let crate_name = self.attributes.crate_name;
|
||||||
let crate_name = attributes.crate_name;
|
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
|
.impl_for_with_lifetimes(format!("{}::BorrowDecode", crate_name), ["__de"])
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
if let Some((bounds, lit)) = (self.attributes.borrow_decode_bounds.as_ref()).or(self.attributes.bounds.as_ref()) {
|
||||||
where_constraints.push_constraint(g, format!("{}::BorrowDecode", crate_name)).unwrap();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
Ok(())
|
||||||
|
})?
|
||||||
.generate_fn("borrow_decode")
|
.generate_fn("borrow_decode")
|
||||||
.with_generic_deps("D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
|
.with_generic_deps("D", [format!("{}::de::BorrowDecoder<'__de>", crate_name)])
|
||||||
.with_arg("decoder", "&mut D")
|
.with_arg("decoder", "&mut D")
|
||||||
|
|
@ -131,7 +150,7 @@ impl DeriveStruct {
|
||||||
fn_body.group(Delimiter::Parenthesis, |ok_group| {
|
fn_body.group(Delimiter::Parenthesis, |ok_group| {
|
||||||
ok_group.ident_str("Self");
|
ok_group.ident_str("Self");
|
||||||
ok_group.group(Delimiter::Brace, |struct_body| {
|
ok_group.group(Delimiter::Brace, |struct_body| {
|
||||||
for field in fields.names() {
|
for field in self.fields.names() {
|
||||||
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
|
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
|
||||||
if attributes.with_serde {
|
if attributes.with_serde {
|
||||||
struct_body
|
struct_body
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ name = "bincode"
|
||||||
version = "2.0.0-rc.1"
|
version = "2.0.0-rc.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode_derive",
|
"bincode_derive",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -121,6 +122,6 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtue"
|
name = "virtue"
|
||||||
version = "0.0.7"
|
version = "0.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "757cfbfe0d17ee6f22fe97e536d463047d451b47cf9d11e2b7d1398b0ef274dd"
|
checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,17 @@ use std::num::{NonZeroI128, NonZeroI32, NonZeroU128, NonZeroU32};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
#[derive(bincode::Decode, bincode::Encode, PartialEq, Debug, serde::Serialize, serde::Deserialize, Eq, PartialOrd, Ord)]
|
#[derive(
|
||||||
|
bincode::Decode,
|
||||||
|
bincode::Encode,
|
||||||
|
PartialEq,
|
||||||
|
Debug,
|
||||||
|
serde::Serialize,
|
||||||
|
serde::Deserialize,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
)]
|
||||||
enum AllTypes {
|
enum AllTypes {
|
||||||
BTreeMap(BTreeMap<u8, AllTypes>),
|
BTreeMap(BTreeMap<u8, AllTypes>),
|
||||||
BTreeSet(BTreeSet<AllTypes>),
|
BTreeSet(BTreeSet<AllTypes>),
|
||||||
|
|
@ -47,14 +57,14 @@ fuzz_target!(|data: &[u8]| {
|
||||||
let bincode_v2: Result<(AllTypes, _), _> = bincode::decode_from_slice(data, config);
|
let bincode_v2: Result<(AllTypes, _), _> = bincode::decode_from_slice(data, config);
|
||||||
|
|
||||||
match (&bincode_v1, &bincode_v2) {
|
match (&bincode_v1, &bincode_v2) {
|
||||||
(Err(e), _) if e.to_string() == "the size limit has been reached" => {},
|
(Err(e), _) if e.to_string() == "the size limit has been reached" => {}
|
||||||
(_, Err(bincode::error::DecodeError::LimitExceeded)) => {},
|
(_, Err(bincode::error::DecodeError::LimitExceeded)) => {}
|
||||||
(Ok(bincode_v1), Ok((bincode_v2, _))) if bincode_v1 != bincode_v2 => {
|
(Ok(bincode_v1), Ok((bincode_v2, _))) if bincode_v1 != bincode_v2 => {
|
||||||
println!("Bytes: {:?}", data);
|
println!("Bytes: {:?}", data);
|
||||||
println!("Bincode V1: {:?}", bincode_v1);
|
println!("Bincode V1: {:?}", bincode_v1);
|
||||||
println!("Bincode V2: {:?}", bincode_v2);
|
println!("Bincode V2: {:?}", bincode_v2);
|
||||||
panic!("failed equality check");
|
panic!("failed equality check");
|
||||||
},
|
}
|
||||||
(Ok(_), Err(_)) | (Err(_), Ok(_)) => {
|
(Ok(_), Err(_)) | (Err(_), Ok(_)) => {
|
||||||
println!("Bytes: {:?}", data);
|
println!("Bytes: {:?}", data);
|
||||||
println!("Bincode V1: {:?}", bincode_v1);
|
println!("Bincode V1: {:?}", bincode_v1);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{de::Decode, enc::Encode};
|
use crate::{de::Decode, enc::Encode, impl_borrow_decode};
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
|
@ -32,6 +32,8 @@ impl Decode for AtomicBool {
|
||||||
Ok(AtomicBool::new(Decode::decode(decoder)?))
|
Ok(AtomicBool::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
|
impl_borrow_decode!(AtomicBool);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
impl Encode for AtomicU8 {
|
impl Encode for AtomicU8 {
|
||||||
|
|
@ -49,6 +51,8 @@ impl Decode for AtomicU8 {
|
||||||
Ok(AtomicU8::new(Decode::decode(decoder)?))
|
Ok(AtomicU8::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
|
impl_borrow_decode!(AtomicU8);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(target_has_atomic = "16")]
|
||||||
impl Encode for AtomicU16 {
|
impl Encode for AtomicU16 {
|
||||||
|
|
@ -66,6 +70,8 @@ impl Decode for AtomicU16 {
|
||||||
Ok(AtomicU16::new(Decode::decode(decoder)?))
|
Ok(AtomicU16::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "16")]
|
||||||
|
impl_borrow_decode!(AtomicU16);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(target_has_atomic = "32")]
|
||||||
impl Encode for AtomicU32 {
|
impl Encode for AtomicU32 {
|
||||||
|
|
@ -83,6 +89,8 @@ impl Decode for AtomicU32 {
|
||||||
Ok(AtomicU32::new(Decode::decode(decoder)?))
|
Ok(AtomicU32::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "32")]
|
||||||
|
impl_borrow_decode!(AtomicU32);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(target_has_atomic = "64")]
|
||||||
impl Encode for AtomicU64 {
|
impl Encode for AtomicU64 {
|
||||||
|
|
@ -100,6 +108,8 @@ impl Decode for AtomicU64 {
|
||||||
Ok(AtomicU64::new(Decode::decode(decoder)?))
|
Ok(AtomicU64::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
|
impl_borrow_decode!(AtomicU64);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
impl Encode for AtomicUsize {
|
impl Encode for AtomicUsize {
|
||||||
|
|
@ -117,6 +127,8 @@ impl Decode for AtomicUsize {
|
||||||
Ok(AtomicUsize::new(Decode::decode(decoder)?))
|
Ok(AtomicUsize::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
impl_borrow_decode!(AtomicUsize);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
impl Encode for AtomicI8 {
|
impl Encode for AtomicI8 {
|
||||||
|
|
@ -134,6 +146,8 @@ impl Decode for AtomicI8 {
|
||||||
Ok(AtomicI8::new(Decode::decode(decoder)?))
|
Ok(AtomicI8::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
|
impl_borrow_decode!(AtomicI8);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(target_has_atomic = "16")]
|
||||||
impl Encode for AtomicI16 {
|
impl Encode for AtomicI16 {
|
||||||
|
|
@ -151,6 +165,8 @@ impl Decode for AtomicI16 {
|
||||||
Ok(AtomicI16::new(Decode::decode(decoder)?))
|
Ok(AtomicI16::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "16")]
|
||||||
|
impl_borrow_decode!(AtomicI16);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(target_has_atomic = "32")]
|
||||||
impl Encode for AtomicI32 {
|
impl Encode for AtomicI32 {
|
||||||
|
|
@ -168,6 +184,8 @@ impl Decode for AtomicI32 {
|
||||||
Ok(AtomicI32::new(Decode::decode(decoder)?))
|
Ok(AtomicI32::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "32")]
|
||||||
|
impl_borrow_decode!(AtomicI32);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(target_has_atomic = "64")]
|
||||||
impl Encode for AtomicI64 {
|
impl Encode for AtomicI64 {
|
||||||
|
|
@ -185,6 +203,8 @@ impl Decode for AtomicI64 {
|
||||||
Ok(AtomicI64::new(Decode::decode(decoder)?))
|
Ok(AtomicI64::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
|
impl_borrow_decode!(AtomicI64);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
impl Encode for AtomicIsize {
|
impl Encode for AtomicIsize {
|
||||||
|
|
@ -202,3 +222,5 @@ impl Decode for AtomicIsize {
|
||||||
Ok(AtomicIsize::new(Decode::decode(decoder)?))
|
Ok(AtomicIsize::new(Decode::decode(decoder)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
impl_borrow_decode!(AtomicIsize);
|
||||||
|
|
|
||||||
|
|
@ -1,141 +1,54 @@
|
||||||
use super::{Decode, Decoder};
|
use super::{BorrowDecode, BorrowDecoder, Decode, Decoder};
|
||||||
use crate::error::DecodeError;
|
use crate::error::DecodeError;
|
||||||
|
|
||||||
impl<A> Decode for (A,)
|
macro_rules! impl_tuple {
|
||||||
where
|
() => {};
|
||||||
A: Decode,
|
($first:ident $(, $extra:ident)*) => {
|
||||||
{
|
impl<'de, $first $(, $extra)*> BorrowDecode<'de> for ($first, $($extra, )*)
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
where
|
||||||
Ok((A::decode(&mut decoder)?,))
|
$first: BorrowDecode<'de>,
|
||||||
|
$(
|
||||||
|
$extra : BorrowDecode<'de>,
|
||||||
|
)*
|
||||||
|
{
|
||||||
|
fn borrow_decode<BD: BorrowDecoder<'de>>(decoder: &mut BD) -> Result<Self, DecodeError> {
|
||||||
|
Ok((
|
||||||
|
$first::borrow_decode(decoder)?,
|
||||||
|
$($extra :: borrow_decode(decoder)?, )*
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$first $(, $extra)*> Decode for ($first, $($extra, )*)
|
||||||
|
where
|
||||||
|
$first: Decode,
|
||||||
|
$(
|
||||||
|
$extra : Decode,
|
||||||
|
)*
|
||||||
|
{
|
||||||
|
fn decode<DE: Decoder>(decoder: &mut DE) -> Result<Self, DecodeError> {
|
||||||
|
Ok((
|
||||||
|
$first::decode(decoder)?,
|
||||||
|
$($extra :: decode(decoder)?, )*
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Decode for (A, B)
|
impl_tuple!(A);
|
||||||
where
|
impl_tuple!(A, B);
|
||||||
A: Decode,
|
impl_tuple!(A, B, C);
|
||||||
B: Decode,
|
impl_tuple!(A, B, C, D);
|
||||||
{
|
impl_tuple!(A, B, C, D, E);
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
impl_tuple!(A, B, C, D, E, F);
|
||||||
Ok((A::decode(&mut decoder)?, B::decode(&mut decoder)?))
|
impl_tuple!(A, B, C, D, E, F, G);
|
||||||
}
|
impl_tuple!(A, B, C, D, E, F, G, H);
|
||||||
}
|
impl_tuple!(A, B, C, D, E, F, G, H, I);
|
||||||
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J);
|
||||||
impl<A, B, C> Decode for (A, B, C)
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K);
|
||||||
where
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
|
||||||
A: Decode,
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
||||||
B: Decode,
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
||||||
C: Decode,
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
||||||
{
|
impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B, C, D> Decode for (A, B, C, D)
|
|
||||||
where
|
|
||||||
A: Decode,
|
|
||||||
B: Decode,
|
|
||||||
C: Decode,
|
|
||||||
D: Decode,
|
|
||||||
{
|
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
D::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B, C, D, E> Decode for (A, B, C, D, E)
|
|
||||||
where
|
|
||||||
A: Decode,
|
|
||||||
B: Decode,
|
|
||||||
C: Decode,
|
|
||||||
D: Decode,
|
|
||||||
E: Decode,
|
|
||||||
{
|
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
D::decode(&mut decoder)?,
|
|
||||||
E::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B, C, D, E, F> Decode for (A, B, C, D, E, F)
|
|
||||||
where
|
|
||||||
A: Decode,
|
|
||||||
B: Decode,
|
|
||||||
C: Decode,
|
|
||||||
D: Decode,
|
|
||||||
E: Decode,
|
|
||||||
F: Decode,
|
|
||||||
{
|
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
D::decode(&mut decoder)?,
|
|
||||||
E::decode(&mut decoder)?,
|
|
||||||
F::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B, C, D, E, F, G> Decode for (A, B, C, D, E, F, G)
|
|
||||||
where
|
|
||||||
A: Decode,
|
|
||||||
B: Decode,
|
|
||||||
C: Decode,
|
|
||||||
D: Decode,
|
|
||||||
E: Decode,
|
|
||||||
F: Decode,
|
|
||||||
G: Decode,
|
|
||||||
{
|
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
D::decode(&mut decoder)?,
|
|
||||||
E::decode(&mut decoder)?,
|
|
||||||
F::decode(&mut decoder)?,
|
|
||||||
G::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B, C, D, E, F, G, H> Decode for (A, B, C, D, E, F, G, H)
|
|
||||||
where
|
|
||||||
A: Decode,
|
|
||||||
B: Decode,
|
|
||||||
C: Decode,
|
|
||||||
D: Decode,
|
|
||||||
E: Decode,
|
|
||||||
F: Decode,
|
|
||||||
G: Decode,
|
|
||||||
H: Decode,
|
|
||||||
{
|
|
||||||
fn decode<_D: Decoder>(mut decoder: &mut _D) -> Result<Self, DecodeError> {
|
|
||||||
Ok((
|
|
||||||
A::decode(&mut decoder)?,
|
|
||||||
B::decode(&mut decoder)?,
|
|
||||||
C::decode(&mut decoder)?,
|
|
||||||
D::decode(&mut decoder)?,
|
|
||||||
E::decode(&mut decoder)?,
|
|
||||||
F::decode(&mut decoder)?,
|
|
||||||
G::decode(&mut decoder)?,
|
|
||||||
H::decode(&mut decoder)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
216
src/de/impls.rs
216
src/de/impls.rs
|
|
@ -8,6 +8,7 @@ use crate::{
|
||||||
InternalIntEncodingConfig,
|
InternalIntEncodingConfig,
|
||||||
},
|
},
|
||||||
error::{DecodeError, IntegerType},
|
error::{DecodeError, IntegerType},
|
||||||
|
impl_borrow_decode,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
|
@ -29,6 +30,7 @@ impl Decode for bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(bool);
|
||||||
|
|
||||||
impl Decode for u8 {
|
impl Decode for u8 {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -45,6 +47,7 @@ impl Decode for u8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(u8);
|
||||||
|
|
||||||
impl Decode for NonZeroU8 {
|
impl Decode for NonZeroU8 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -53,6 +56,7 @@ impl Decode for NonZeroU8 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroU8);
|
||||||
|
|
||||||
impl Decode for u16 {
|
impl Decode for u16 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -72,6 +76,7 @@ impl Decode for u16 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(u16);
|
||||||
|
|
||||||
impl Decode for NonZeroU16 {
|
impl Decode for NonZeroU16 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -80,6 +85,7 @@ impl Decode for NonZeroU16 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroU16);
|
||||||
|
|
||||||
impl Decode for u32 {
|
impl Decode for u32 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -99,6 +105,7 @@ impl Decode for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(u32);
|
||||||
|
|
||||||
impl Decode for NonZeroU32 {
|
impl Decode for NonZeroU32 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -107,6 +114,7 @@ impl Decode for NonZeroU32 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroU32);
|
||||||
|
|
||||||
impl Decode for u64 {
|
impl Decode for u64 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -126,6 +134,7 @@ impl Decode for u64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(u64);
|
||||||
|
|
||||||
impl Decode for NonZeroU64 {
|
impl Decode for NonZeroU64 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -134,6 +143,7 @@ impl Decode for NonZeroU64 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroU64);
|
||||||
|
|
||||||
impl Decode for u128 {
|
impl Decode for u128 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -153,6 +163,7 @@ impl Decode for u128 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(u128);
|
||||||
|
|
||||||
impl Decode for NonZeroU128 {
|
impl Decode for NonZeroU128 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -161,6 +172,7 @@ impl Decode for NonZeroU128 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroU128);
|
||||||
|
|
||||||
impl Decode for usize {
|
impl Decode for usize {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -185,6 +197,7 @@ impl Decode for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(usize);
|
||||||
|
|
||||||
impl Decode for NonZeroUsize {
|
impl Decode for NonZeroUsize {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -193,6 +206,7 @@ impl Decode for NonZeroUsize {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroUsize);
|
||||||
|
|
||||||
impl Decode for i8 {
|
impl Decode for i8 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -202,6 +216,7 @@ impl Decode for i8 {
|
||||||
Ok(bytes[0] as i8)
|
Ok(bytes[0] as i8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(i8);
|
||||||
|
|
||||||
impl Decode for NonZeroI8 {
|
impl Decode for NonZeroI8 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -210,6 +225,7 @@ impl Decode for NonZeroI8 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroI8);
|
||||||
|
|
||||||
impl Decode for i16 {
|
impl Decode for i16 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -229,6 +245,7 @@ impl Decode for i16 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(i16);
|
||||||
|
|
||||||
impl Decode for NonZeroI16 {
|
impl Decode for NonZeroI16 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -237,6 +254,7 @@ impl Decode for NonZeroI16 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroI16);
|
||||||
|
|
||||||
impl Decode for i32 {
|
impl Decode for i32 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -256,6 +274,7 @@ impl Decode for i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(i32);
|
||||||
|
|
||||||
impl Decode for NonZeroI32 {
|
impl Decode for NonZeroI32 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -264,6 +283,7 @@ impl Decode for NonZeroI32 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroI32);
|
||||||
|
|
||||||
impl Decode for i64 {
|
impl Decode for i64 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -283,6 +303,7 @@ impl Decode for i64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(i64);
|
||||||
|
|
||||||
impl Decode for NonZeroI64 {
|
impl Decode for NonZeroI64 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -291,6 +312,7 @@ impl Decode for NonZeroI64 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroI64);
|
||||||
|
|
||||||
impl Decode for i128 {
|
impl Decode for i128 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -310,6 +332,7 @@ impl Decode for i128 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(i128);
|
||||||
|
|
||||||
impl Decode for NonZeroI128 {
|
impl Decode for NonZeroI128 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -318,6 +341,7 @@ impl Decode for NonZeroI128 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroI128);
|
||||||
|
|
||||||
impl Decode for isize {
|
impl Decode for isize {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -337,6 +361,7 @@ impl Decode for isize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(isize);
|
||||||
|
|
||||||
impl Decode for NonZeroIsize {
|
impl Decode for NonZeroIsize {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -345,6 +370,7 @@ impl Decode for NonZeroIsize {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(NonZeroIsize);
|
||||||
|
|
||||||
impl Decode for f32 {
|
impl Decode for f32 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -357,6 +383,7 @@ impl Decode for f32 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(f32);
|
||||||
|
|
||||||
impl Decode for f64 {
|
impl Decode for f64 {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -369,6 +396,7 @@ impl Decode for f64 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(f64);
|
||||||
|
|
||||||
impl Decode for char {
|
impl Decode for char {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -398,6 +426,7 @@ impl Decode for char {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(char);
|
||||||
|
|
||||||
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a [u8] {
|
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a [u8] {
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
|
@ -407,18 +436,6 @@ impl<'a, 'de: 'a> BorrowDecode<'de> for &'a [u8] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'de: 'a> BorrowDecode<'de> for Option<&'a [u8]> {
|
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
|
||||||
match super::decode_option_variant(decoder, core::any::type_name::<Option<&[u8]>>())? {
|
|
||||||
Some(_) => {
|
|
||||||
let val = BorrowDecode::borrow_decode(decoder)?;
|
|
||||||
Ok(Some(val))
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str {
|
impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str {
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
let slice = <&[u8]>::borrow_decode(decoder)?;
|
let slice = <&[u8]>::borrow_decode(decoder)?;
|
||||||
|
|
@ -426,18 +443,6 @@ impl<'a, 'de: 'a> BorrowDecode<'de> for &'a str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'de: 'a> BorrowDecode<'de> for Option<&'a str> {
|
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
|
||||||
match super::decode_option_variant(decoder, core::any::type_name::<Option<&str>>())? {
|
|
||||||
Some(_) => {
|
|
||||||
let val = BorrowDecode::borrow_decode(decoder)?;
|
|
||||||
Ok(Some(val))
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, const N: usize> Decode for [T; N]
|
impl<T, const N: usize> Decode for [T; N]
|
||||||
where
|
where
|
||||||
T: Decode + Sized + 'static,
|
T: Decode + Sized + 'static,
|
||||||
|
|
@ -479,17 +484,64 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T, const N: usize> BorrowDecode<'de> for [T; N]
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de> + Sized + 'static,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
if !D::C::SKIP_FIXED_ARRAY_LENGTH {
|
||||||
|
let length = super::decode_slice_len(decoder)?;
|
||||||
|
if length != N {
|
||||||
|
return Err(DecodeError::ArrayLengthMismatch {
|
||||||
|
found: length,
|
||||||
|
required: N,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
|
||||||
|
|
||||||
|
// Optimize for `[u8; N]`
|
||||||
|
if TypeId::of::<u8>() == TypeId::of::<T>() {
|
||||||
|
let mut buf = [0u8; N];
|
||||||
|
decoder.reader().read(&mut buf)?;
|
||||||
|
let ptr = &mut buf as *mut _ as *mut [T; N];
|
||||||
|
|
||||||
|
// Safety: we know that T is a u8, so it is perfectly safe to
|
||||||
|
// translate an array of u8 into an array of T
|
||||||
|
let res = unsafe { ptr.read() };
|
||||||
|
Ok(res)
|
||||||
|
} else {
|
||||||
|
let result = super::impl_core::collect_into_array(&mut (0..N).map(|_| {
|
||||||
|
// See the documentation on `unclaim_bytes_read` as to why we're doing this here
|
||||||
|
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||||
|
T::borrow_decode(decoder)
|
||||||
|
}));
|
||||||
|
|
||||||
|
// result is only None if N does not match the values of `(0..N)`, which it always should
|
||||||
|
// So this unwrap should never occur
|
||||||
|
result.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Decode for () {
|
impl Decode for () {
|
||||||
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(());
|
||||||
|
|
||||||
impl<T> Decode for core::marker::PhantomData<T> {
|
impl<T> Decode for core::marker::PhantomData<T> {
|
||||||
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(_: &mut D) -> Result<Self, DecodeError> {
|
||||||
Ok(core::marker::PhantomData)
|
Ok(core::marker::PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for core::marker::PhantomData<T> {
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(_: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
Ok(core::marker::PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Decode for Option<T>
|
impl<T> Decode for Option<T>
|
||||||
where
|
where
|
||||||
|
|
@ -506,6 +558,37 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Option<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(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)?;
|
||||||
|
Ok(Some(val))
|
||||||
|
}
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockedTODO: https://github.com/rust-lang/rust/issues/37653
|
||||||
|
//
|
||||||
|
// We'll want to implement BorrowDecode for both Option<&[u8]> and Option<&[T: Encode]>,
|
||||||
|
// but those implementations overlap because &'a [u8] also implements BorrowDecode
|
||||||
|
// impl<'a, 'de: 'a> BorrowDecode<'de> for Option<&'a [u8]> {
|
||||||
|
// fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
// match super::decode_option_variant(decoder, core::any::type_name::<Option<&[u8]>>())? {
|
||||||
|
// Some(_) => {
|
||||||
|
// let val = BorrowDecode::borrow_decode(decoder)?;
|
||||||
|
// Ok(Some(val))
|
||||||
|
// }
|
||||||
|
// None => Ok(None),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl<T, U> Decode for Result<T, U>
|
impl<T, U> Decode for Result<T, U>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
@ -531,6 +614,31 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T, U> BorrowDecode<'de> for Result<T, U>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
U: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let is_ok = u32::decode(decoder)?;
|
||||||
|
match is_ok {
|
||||||
|
0 => {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(Ok(t))
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let u = U::borrow_decode(decoder)?;
|
||||||
|
Ok(Err(u))
|
||||||
|
}
|
||||||
|
x => Err(DecodeError::UnexpectedVariant {
|
||||||
|
found: x as u32,
|
||||||
|
allowed: crate::error::AllowedEnumVariants::Range { max: 1, min: 0 },
|
||||||
|
type_name: core::any::type_name::<Result<T, U>>(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Decode for Cell<T>
|
impl<T> Decode for Cell<T>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
@ -541,6 +649,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Cell<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(Cell::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Decode for RefCell<T>
|
impl<T> Decode for RefCell<T>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
@ -551,6 +669,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for RefCell<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(RefCell::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Decode for Duration {
|
impl Decode for Duration {
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
const NANOS_PER_SEC: u64 = 1_000_000_000;
|
const NANOS_PER_SEC: u64 = 1_000_000_000;
|
||||||
|
|
@ -562,6 +690,7 @@ impl Decode for Duration {
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(Duration);
|
||||||
|
|
||||||
impl<T> Decode for Range<T>
|
impl<T> Decode for Range<T>
|
||||||
where
|
where
|
||||||
|
|
@ -573,6 +702,16 @@ where
|
||||||
Ok(min..max)
|
Ok(min..max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Range<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(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<T> Decode for RangeInclusive<T>
|
||||||
where
|
where
|
||||||
|
|
@ -585,6 +724,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for RangeInclusive<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(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> Decode for Bound<T>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
@ -603,6 +753,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Bound<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
match u32::decode(decoder)? {
|
||||||
|
0 => Ok(Bound::Unbounded),
|
||||||
|
1 => Ok(Bound::Included(T::borrow_decode(decoder)?)),
|
||||||
|
2 => Ok(Bound::Excluded(T::borrow_decode(decoder)?)),
|
||||||
|
x => Err(DecodeError::UnexpectedVariant {
|
||||||
|
allowed: crate::error::AllowedEnumVariants::Range { max: 2, min: 0 },
|
||||||
|
found: x,
|
||||||
|
type_name: core::any::type_name::<Bound<T>>(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const UTF8_CHAR_WIDTH: [u8; 256] = [
|
const UTF8_CHAR_WIDTH: [u8; 256] = [
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, // 0x1F
|
1, // 0x1F
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,16 @@ pub use self::decoder::DecoderImpl;
|
||||||
/// })
|
/// })
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
/// impl<'de> bincode::BorrowDecode<'de> for Entity {
|
||||||
|
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de>>(
|
||||||
|
/// decoder: &mut D,
|
||||||
|
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
|
||||||
|
/// Ok(Self {
|
||||||
|
/// x: bincode::BorrowDecode::borrow_decode(decoder)?,
|
||||||
|
/// y: bincode::BorrowDecode::borrow_decode(decoder)?,
|
||||||
|
/// })
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// From here you can add/remove fields, or add custom logic.
|
/// From here you can add/remove fields, or add custom logic.
|
||||||
|
|
@ -70,8 +80,9 @@ pub use self::decoder::DecoderImpl;
|
||||||
/// # Ok(Foo)
|
/// # Ok(Foo)
|
||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
|
/// # bincode::impl_borrow_decode!(Foo);
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Decode: for<'de> BorrowDecode<'de> {
|
pub trait Decode: Sized {
|
||||||
/// Attempt to decode this type with the given [Decode].
|
/// Attempt to decode this type with the given [Decode].
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
|
||||||
}
|
}
|
||||||
|
|
@ -86,10 +97,18 @@ pub trait BorrowDecode<'de>: Sized {
|
||||||
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError>;
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, T: Decode> BorrowDecode<'de> for T {
|
/// Helper macro to implement `BorrowDecode` for any type that implements `Decode`.
|
||||||
fn borrow_decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
#[macro_export]
|
||||||
Decode::decode(decoder)
|
macro_rules! impl_borrow_decode {
|
||||||
}
|
($ty:ty) => {
|
||||||
|
impl<'de> $crate::BorrowDecode<'de> for $ty {
|
||||||
|
fn borrow_decode<D: $crate::de::BorrowDecoder<'de>>(
|
||||||
|
decoder: &mut D,
|
||||||
|
) -> core::result::Result<Self, $crate::error::DecodeError> {
|
||||||
|
$crate::Decode::decode(decoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any source that can decode basic types. This type is most notably implemented for [Decoder].
|
/// Any source that can decode basic types. This type is most notably implemented for [Decoder].
|
||||||
|
|
@ -163,6 +182,24 @@ pub trait Decoder: Sealed {
|
||||||
/// Ok(result)
|
/// Ok(result)
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
/// impl<'de, T: bincode::BorrowDecode<'de>> bincode::BorrowDecode<'de> for Container<T> {
|
||||||
|
/// fn borrow_decode<D: bincode::de::BorrowDecoder<'de>>(
|
||||||
|
/// decoder: &mut D,
|
||||||
|
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
|
||||||
|
/// let len = u64::borrow_decode(decoder)?;
|
||||||
|
/// let len: usize = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
|
||||||
|
/// // Make sure we don't allocate too much memory
|
||||||
|
/// decoder.claim_bytes_read(len * core::mem::size_of::<T>());
|
||||||
|
///
|
||||||
|
/// let mut result = Container::with_capacity(len);
|
||||||
|
/// for _ in 0..len {
|
||||||
|
/// // un-claim the memory
|
||||||
|
/// decoder.unclaim_bytes_read(core::mem::size_of::<T>());
|
||||||
|
/// result.push(T::borrow_decode(decoder)?)
|
||||||
|
/// }
|
||||||
|
/// Ok(result)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
fn unclaim_bytes_read(&mut self, n: usize);
|
fn unclaim_bytes_read(&mut self, n: usize);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -283,12 +283,12 @@ impl Encode for char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encode for &'_ [u8] {
|
// impl Encode for &'_ [u8] {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
// fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
super::encode_slice_len(encoder, self.len())?;
|
// super::encode_slice_len(encoder, self.len())?;
|
||||||
encoder.writer().write(self)
|
// encoder.writer().write(self)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const TAG_CONT: u8 = 0b1000_0000;
|
const TAG_CONT: u8 = 0b1000_0000;
|
||||||
const TAG_TWO_B: u8 = 0b1100_0000;
|
const TAG_TWO_B: u8 = 0b1100_0000;
|
||||||
|
|
@ -327,25 +327,24 @@ fn encode_utf8(writer: &mut impl Writer, c: char) -> Result<(), EncodeError> {
|
||||||
// BlockedTODO: https://github.com/rust-lang/rust/issues/37653
|
// BlockedTODO: https://github.com/rust-lang/rust/issues/37653
|
||||||
//
|
//
|
||||||
// We'll want to implement encoding for both &[u8] and &[T: Encode],
|
// We'll want to implement encoding for both &[u8] and &[T: Encode],
|
||||||
// but those implementations overlap because u8 also implements Encodeabl
|
// but those implementations overlap because u8 also implements Encode
|
||||||
//
|
// impl Encode for &'_ [u8] {
|
||||||
// default impl Encode for &'_ [u8] {
|
// fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
// fn encode<E: Encode>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
// encoder.writer().write(*self)
|
||||||
// encoder.encode_slice(*self)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// impl<T: Encode> Encode for &'_ [T] {
|
|
||||||
// fn encode<E: Encode>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
|
||||||
// self.len().encode(encoder)?;
|
|
||||||
// for item in self.iter() {
|
|
||||||
// item.encode(encoder)?;
|
|
||||||
// }
|
|
||||||
// Ok(())
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl Encode for &'_ str {
|
impl<T: Encode> Encode for &'_ [T] {
|
||||||
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
self.len().encode(encoder)?;
|
||||||
|
for item in self.iter() {
|
||||||
|
item.encode(encoder)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for str {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
self.as_bytes().encode(encoder)
|
self.as_bytes().encode(encoder)
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +408,7 @@ where
|
||||||
|
|
||||||
impl<T> Encode for RefCell<T>
|
impl<T> Encode for RefCell<T>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode + ?Sized,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
let borrow_guard = self
|
let borrow_guard = self
|
||||||
|
|
@ -476,7 +475,7 @@ where
|
||||||
|
|
||||||
impl<'a, T> Encode for &'a T
|
impl<'a, T> Encode for &'a T
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode + ?Sized,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
T::encode(self, encoder)
|
T::encode(self, encoder)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
de::{Decode, Decoder},
|
de::{BorrowDecoder, Decode, Decoder},
|
||||||
enc::{self, Encode, Encoder},
|
enc::{self, Encode, Encoder},
|
||||||
error::{DecodeError, EncodeError},
|
error::{DecodeError, EncodeError},
|
||||||
Config,
|
impl_borrow_decode, BorrowDecode, Config,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "atomic")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::{
|
use alloc::{
|
||||||
borrow::{Cow, ToOwned},
|
borrow::{Cow, ToOwned},
|
||||||
|
|
@ -65,6 +65,25 @@ where
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for BinaryHeap<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de> + Ord,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<T>(len)?;
|
||||||
|
|
||||||
|
let mut map = BinaryHeap::with_capacity(len);
|
||||||
|
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>());
|
||||||
|
|
||||||
|
let key = T::borrow_decode(decoder)?;
|
||||||
|
map.push(key);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for BinaryHeap<T>
|
impl<T> Encode for BinaryHeap<T>
|
||||||
where
|
where
|
||||||
|
|
@ -100,6 +119,27 @@ where
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, K, V> BorrowDecode<'de> for BTreeMap<K, V>
|
||||||
|
where
|
||||||
|
K: BorrowDecode<'de> + Ord,
|
||||||
|
V: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<(K, V)>(len)?;
|
||||||
|
|
||||||
|
let mut map = BTreeMap::new();
|
||||||
|
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::<(K, V)>());
|
||||||
|
|
||||||
|
let key = K::borrow_decode(decoder)?;
|
||||||
|
let value = V::borrow_decode(decoder)?;
|
||||||
|
map.insert(key, value);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<K, V> Encode for BTreeMap<K, V>
|
impl<K, V> Encode for BTreeMap<K, V>
|
||||||
where
|
where
|
||||||
|
|
@ -135,6 +175,25 @@ where
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for BTreeSet<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de> + Ord,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<T>(len)?;
|
||||||
|
|
||||||
|
let mut map = BTreeSet::new();
|
||||||
|
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>());
|
||||||
|
|
||||||
|
let key = T::borrow_decode(decoder)?;
|
||||||
|
map.insert(key);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for BTreeSet<T>
|
impl<T> Encode for BTreeSet<T>
|
||||||
where
|
where
|
||||||
|
|
@ -168,6 +227,25 @@ where
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for VecDeque<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<T>(len)?;
|
||||||
|
|
||||||
|
let mut map = VecDeque::with_capacity(len);
|
||||||
|
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>());
|
||||||
|
|
||||||
|
let key = T::borrow_decode(decoder)?;
|
||||||
|
map.push_back(key);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for VecDeque<T>
|
impl<T> Encode for VecDeque<T>
|
||||||
where
|
where
|
||||||
|
|
@ -201,6 +279,25 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Vec<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<T>(len)?;
|
||||||
|
|
||||||
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
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(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for Vec<T>
|
impl<T> Encode for Vec<T>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
|
|
@ -222,6 +319,7 @@ impl Decode for String {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(String);
|
||||||
|
|
||||||
impl Encode for String {
|
impl Encode for String {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -238,10 +336,19 @@ where
|
||||||
Ok(Box::new(t))
|
Ok(Box::new(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Box<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(Box::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for Box<T>
|
impl<T> Encode for Box<T>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode + ?Sized,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
T::encode(self, encoder)
|
T::encode(self, encoder)
|
||||||
|
|
@ -258,6 +365,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Box<[T]>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de> + 'de,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let vec = Vec::borrow_decode(decoder)?;
|
||||||
|
Ok(vec.into_boxed_slice())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for Box<[T]>
|
impl<T> Encode for Box<[T]>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
|
|
@ -271,20 +388,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockedTODO: https://github.com/rust-lang/rust/issues/31844
|
|
||||||
// Cow should be able to decode a borrowed value
|
|
||||||
// Currently this conflicts with the owned `Decode` implementation below
|
|
||||||
|
|
||||||
// impl<'cow, T> BorrowDecode<'cow> for Cow<'cow, T>
|
|
||||||
// where
|
|
||||||
// T: BorrowDecode<'cow>,
|
|
||||||
// {
|
|
||||||
// fn borrow_decode<D: crate::de::BorrowDecoder<'cow>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
|
||||||
// let t = T::borrow_decode(decoder)?;
|
|
||||||
// Ok(Cow::Borrowed(t))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl<'cow, T> Decode for Cow<'cow, T>
|
impl<'cow, T> Decode for Cow<'cow, T>
|
||||||
where
|
where
|
||||||
T: ToOwned + ?Sized,
|
T: ToOwned + ?Sized,
|
||||||
|
|
@ -295,6 +398,16 @@ where
|
||||||
Ok(Cow::Owned(t))
|
Ok(Cow::Owned(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'cow, T> BorrowDecode<'cow> for Cow<'cow, T>
|
||||||
|
where
|
||||||
|
T: ToOwned + ?Sized,
|
||||||
|
&'cow T: BorrowDecode<'cow>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'cow>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = <&T>::borrow_decode(decoder)?;
|
||||||
|
Ok(Cow::Borrowed(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'cow, T> Encode for Cow<'cow, T>
|
impl<'cow, T> Encode for Cow<'cow, T>
|
||||||
where
|
where
|
||||||
|
|
@ -316,16 +429,26 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Rc<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(Rc::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for Rc<T>
|
impl<T> Encode for Rc<T>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode + ?Sized,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
T::encode(self, encoder)
|
T::encode(self, encoder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "atomic")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
impl<T> Decode for Arc<T>
|
impl<T> Decode for Arc<T>
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
@ -336,10 +459,37 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "atomic")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
impl Decode for Arc<str> {
|
||||||
|
fn decode<D: Decoder>(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>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(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> {
|
||||||
|
let decoded = String::decode(decoder)?;
|
||||||
|
Ok(decoded.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
impl<T> Encode for Arc<T>
|
impl<T> Encode for Arc<T>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode + ?Sized,
|
||||||
{
|
{
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
T::encode(self, encoder)
|
T::encode(self, encoder)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
de::{read::Reader, BorrowDecode, BorrowDecoder, Decode, Decoder, DecoderImpl},
|
de::{read::Reader, BorrowDecode, BorrowDecoder, Decode, Decoder, DecoderImpl},
|
||||||
enc::{write::Writer, Encode, Encoder, EncoderImpl},
|
enc::{write::Writer, Encode, Encoder, EncoderImpl},
|
||||||
error::{DecodeError, EncodeError},
|
error::{DecodeError, EncodeError},
|
||||||
|
impl_borrow_decode,
|
||||||
};
|
};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -146,6 +147,7 @@ impl Decode for CString {
|
||||||
CString::new(vec).map_err(|inner| DecodeError::CStringNulError { inner })
|
CString::new(vec).map_err(|inner| DecodeError::CStringNulError { inner })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(CString);
|
||||||
|
|
||||||
impl<T> Encode for Mutex<T>
|
impl<T> Encode for Mutex<T>
|
||||||
where
|
where
|
||||||
|
|
@ -168,6 +170,15 @@ where
|
||||||
Ok(Mutex::new(t))
|
Ok(Mutex::new(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for Mutex<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(Mutex::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Encode for RwLock<T>
|
impl<T> Encode for RwLock<T>
|
||||||
where
|
where
|
||||||
|
|
@ -190,6 +201,15 @@ where
|
||||||
Ok(RwLock::new(t))
|
Ok(RwLock::new(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> BorrowDecode<'de> for RwLock<T>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::borrow_decode(decoder)?;
|
||||||
|
Ok(RwLock::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for SystemTime {
|
impl Encode for SystemTime {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -212,6 +232,7 @@ impl Decode for SystemTime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(SystemTime);
|
||||||
|
|
||||||
impl Encode for &'_ Path {
|
impl Encode for &'_ Path {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -241,6 +262,7 @@ impl Decode for PathBuf {
|
||||||
Ok(string.into())
|
Ok(string.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(PathBuf);
|
||||||
|
|
||||||
impl Encode for IpAddr {
|
impl Encode for IpAddr {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -270,6 +292,7 @@ impl Decode for IpAddr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(IpAddr);
|
||||||
|
|
||||||
impl Encode for Ipv4Addr {
|
impl Encode for Ipv4Addr {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -284,6 +307,7 @@ impl Decode for Ipv4Addr {
|
||||||
Ok(Self::from(buff))
|
Ok(Self::from(buff))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(Ipv4Addr);
|
||||||
|
|
||||||
impl Encode for Ipv6Addr {
|
impl Encode for Ipv6Addr {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -298,6 +322,7 @@ impl Decode for Ipv6Addr {
|
||||||
Ok(Self::from(buff))
|
Ok(Self::from(buff))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(Ipv6Addr);
|
||||||
|
|
||||||
impl Encode for SocketAddr {
|
impl Encode for SocketAddr {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -327,6 +352,7 @@ impl Decode for SocketAddr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(SocketAddr);
|
||||||
|
|
||||||
impl Encode for SocketAddrV4 {
|
impl Encode for SocketAddrV4 {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -342,6 +368,7 @@ impl Decode for SocketAddrV4 {
|
||||||
Ok(Self::new(ip, port))
|
Ok(Self::new(ip, port))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(SocketAddrV4);
|
||||||
|
|
||||||
impl Encode for SocketAddrV6 {
|
impl Encode for SocketAddrV6 {
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
|
@ -357,6 +384,7 @@ impl Decode for SocketAddrV6 {
|
||||||
Ok(Self::new(ip, port, 0, 0))
|
Ok(Self::new(ip, port, 0, 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl_borrow_decode!(SocketAddrV6);
|
||||||
|
|
||||||
impl std::error::Error for EncodeError {
|
impl std::error::Error for EncodeError {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
|
@ -416,6 +444,27 @@ where
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, K, V> BorrowDecode<'de> for HashMap<K, V>
|
||||||
|
where
|
||||||
|
K: BorrowDecode<'de> + Eq + std::hash::Hash,
|
||||||
|
V: BorrowDecode<'de>,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<(K, V)>(len)?;
|
||||||
|
|
||||||
|
let mut map = HashMap::with_capacity(len);
|
||||||
|
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::<(K, V)>());
|
||||||
|
|
||||||
|
let k = K::borrow_decode(decoder)?;
|
||||||
|
let v = V::borrow_decode(decoder)?;
|
||||||
|
map.insert(k, v);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> Decode for HashSet<T, S>
|
impl<T, S> Decode for HashSet<T, S>
|
||||||
where
|
where
|
||||||
|
|
@ -439,6 +488,27 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T, S> BorrowDecode<'de> for HashSet<T, S>
|
||||||
|
where
|
||||||
|
T: BorrowDecode<'de> + Eq + Hash,
|
||||||
|
S: std::hash::BuildHasher + Default,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let len = crate::de::decode_slice_len(decoder)?;
|
||||||
|
decoder.claim_container_read::<T>(len)?;
|
||||||
|
|
||||||
|
let mut map = HashSet::with_capacity_and_hasher(len, S::default());
|
||||||
|
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>());
|
||||||
|
|
||||||
|
let key = T::borrow_decode(decoder)?;
|
||||||
|
map.insert(key);
|
||||||
|
}
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> Encode for HashSet<T, S>
|
impl<T, S> Encode for HashSet<T, S>
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,17 @@ where
|
||||||
T::deserialize(serde_decoder).map(Compat)
|
T::deserialize(serde_decoder).map(Compat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'de, T> crate::BorrowDecode<'de> for Compat<T>
|
||||||
|
where
|
||||||
|
T: serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: crate::de::BorrowDecoder<'de>>(
|
||||||
|
decoder: &mut D,
|
||||||
|
) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
let serde_decoder = de_owned::SerdeDecoder { de: decoder };
|
||||||
|
T::deserialize(serde_decoder).map(Compat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> crate::Encode for Compat<T>
|
impl<T> crate::Encode for Compat<T>
|
||||||
where
|
where
|
||||||
|
|
|
||||||
19
src/lib.rs
19
src/lib.rs
|
|
@ -90,6 +90,7 @@ use enc::write::Writer;
|
||||||
pub use features::*;
|
pub use features::*;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
#[macro_use]
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod enc;
|
pub mod enc;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
@ -136,7 +137,23 @@ pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(
|
||||||
/// See the [config] module for more information on configurations.
|
/// See the [config] module for more information on configurations.
|
||||||
///
|
///
|
||||||
/// [config]: config/index.html
|
/// [config]: config/index.html
|
||||||
pub fn decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>(
|
pub fn decode_from_slice<D: de::Decode, C: Config>(
|
||||||
|
src: &[u8],
|
||||||
|
config: C,
|
||||||
|
) -> Result<(D, usize), error::DecodeError> {
|
||||||
|
let reader = de::read::SliceReader::new(src);
|
||||||
|
let mut decoder = de::DecoderImpl::<_, C>::new(reader, config);
|
||||||
|
let result = D::decode(&mut decoder)?;
|
||||||
|
let bytes_read = src.len() - decoder.reader().slice.len();
|
||||||
|
Ok((result, bytes_read))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempt to decode a given type `D` from the given slice.
|
||||||
|
///
|
||||||
|
/// 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>(
|
||||||
src: &'a [u8],
|
src: &'a [u8],
|
||||||
config: C,
|
config: C,
|
||||||
) -> Result<(D, usize), error::DecodeError> {
|
) -> Result<(D, usize), error::DecodeError> {
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,7 @@ fn test_decode_u64() {
|
||||||
(&[U32_BYTE, 0, 0, 0, 10], 167_772_160, 10),
|
(&[U32_BYTE, 0, 0, 0, 10], 167_772_160, 10),
|
||||||
(
|
(
|
||||||
&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0, 10],
|
&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0, 10],
|
||||||
72_057_594_037_9279_360,
|
720_575_940_379_279_360,
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
@ -574,7 +574,7 @@ fn test_decode_u128() {
|
||||||
(&[U32_BYTE, 0, 0, 0, 10], 167_772_160, 10),
|
(&[U32_BYTE, 0, 0, 0, 10], 167_772_160, 10),
|
||||||
(
|
(
|
||||||
&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0, 10],
|
&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0, 10],
|
||||||
72_057_594_037_9279_360,
|
720_575_940_379_279_360,
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ fn test_encode_u64() {
|
||||||
|
|
||||||
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
||||||
// Values chosen at random, add new cases as needed
|
// Values chosen at random, add new cases as needed
|
||||||
for i in [u32::MAX as u64 + 1, 500_0000_000, u64::MAX] {
|
for i in [u32::MAX as u64 + 1, 5_000_000_000, u64::MAX] {
|
||||||
let mut writer = SliceWriter::new(&mut buffer);
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
varint_encode_u64(&mut writer, Endian::Big, i).unwrap();
|
||||||
assert_eq!(writer.bytes_written(), 9);
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
|
@ -351,7 +351,7 @@ fn test_encode_u128() {
|
||||||
|
|
||||||
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
// these values should encode in 9 bytes (leading byte + 8 bytes)
|
||||||
// Values chosen at random, add new cases as needed
|
// Values chosen at random, add new cases as needed
|
||||||
for i in [u32::MAX as u128 + 1, 500_0000_000, u64::MAX as u128] {
|
for i in [u32::MAX as u128 + 1, 5_000_000_000, u64::MAX as u128] {
|
||||||
let mut writer = SliceWriter::new(&mut buffer);
|
let mut writer = SliceWriter::new(&mut buffer);
|
||||||
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
varint_encode_u128(&mut writer, Endian::Big, i).unwrap();
|
||||||
assert_eq!(writer.bytes_written(), 9);
|
assert_eq!(writer.bytes_written(), 9);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::blacklisted_name)]
|
||||||
#![cfg(feature = "alloc")]
|
#![cfg(feature = "alloc")]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
@ -8,7 +9,7 @@ use alloc::borrow::Cow;
|
||||||
use alloc::collections::*;
|
use alloc::collections::*;
|
||||||
#[cfg(not(feature = "serde"))]
|
#[cfg(not(feature = "serde"))]
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
#[cfg(all(feature = "atomic", not(feature = "serde")))]
|
#[cfg(all(target_has_atomic = "ptr", not(feature = "serde")))]
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use utils::{the_same, the_same_with_comparer};
|
use utils::{the_same, the_same_with_comparer};
|
||||||
|
|
||||||
|
|
@ -38,6 +39,7 @@ impl bincode::Decode for Foo {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bincode::impl_borrow_decode!(Foo);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vec() {
|
fn test_vec() {
|
||||||
|
|
@ -49,6 +51,30 @@ fn test_vec() {
|
||||||
assert_eq!(foo.a, 5);
|
assert_eq!(foo.a, 5);
|
||||||
assert_eq!(foo.b, 10);
|
assert_eq!(foo.b, 10);
|
||||||
assert_eq!(len, 2);
|
assert_eq!(len, 2);
|
||||||
|
|
||||||
|
let vec: Vec<u8> = bincode::decode_from_slice(
|
||||||
|
&[4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4],
|
||||||
|
bincode::config::legacy(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.0;
|
||||||
|
assert_eq!(vec, &[1, 2, 3, 4]);
|
||||||
|
|
||||||
|
let vec: Vec<Cow<'static, u8>> = bincode::decode_from_slice(
|
||||||
|
&[4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4],
|
||||||
|
bincode::config::legacy(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.0;
|
||||||
|
assert_eq!(
|
||||||
|
vec,
|
||||||
|
&[
|
||||||
|
Cow::Borrowed(&1),
|
||||||
|
Cow::Borrowed(&2),
|
||||||
|
Cow::Borrowed(&3),
|
||||||
|
Cow::Borrowed(&4)
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -59,12 +85,16 @@ fn test_alloc_commons() {
|
||||||
the_same(Box::<[u32]>::from(vec![1, 2, 3, 4, 5]));
|
the_same(Box::<[u32]>::from(vec![1, 2, 3, 4, 5]));
|
||||||
the_same(Cow::<u32>::Owned(5));
|
the_same(Cow::<u32>::Owned(5));
|
||||||
the_same(Cow::<u32>::Borrowed(&5));
|
the_same(Cow::<u32>::Borrowed(&5));
|
||||||
// Serde doesn't support Rc<u32>
|
|
||||||
#[cfg(not(feature = "serde"))]
|
#[cfg(not(feature = "serde"))]
|
||||||
the_same(Rc::<u32>::new(5));
|
{
|
||||||
// serde doesn't support Arc<u32>
|
// Serde doesn't support Rc or Arc
|
||||||
#[cfg(all(feature = "atomic", not(feature = "serde")))]
|
the_same(Rc::<u32>::new(5));
|
||||||
the_same(Arc::<u32>::new(5));
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
{
|
||||||
|
the_same(Arc::<u32>::new(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
the_same_with_comparer(
|
the_same_with_comparer(
|
||||||
{
|
{
|
||||||
let mut map = BinaryHeap::<u32>::new();
|
let mut map = BinaryHeap::<u32>::new();
|
||||||
|
|
@ -75,7 +105,7 @@ fn test_alloc_commons() {
|
||||||
map.push(5);
|
map.push(5);
|
||||||
map
|
map
|
||||||
},
|
},
|
||||||
|a, b| a.into_iter().collect::<Vec<_>>() == b.into_iter().collect::<Vec<_>>(),
|
|a, b| a.iter().collect::<Vec<_>>() == b.iter().collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
the_same({
|
the_same({
|
||||||
let mut map = BTreeMap::<u32, i32>::new();
|
let mut map = BTreeMap::<u32, i32>::new();
|
||||||
|
|
@ -97,7 +127,7 @@ fn test_alloc_commons() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_container_limits() {
|
fn test_container_limits() {
|
||||||
use bincode::{error::DecodeError, Decode};
|
use bincode::{error::DecodeError, BorrowDecode, Decode};
|
||||||
|
|
||||||
const DECODE_LIMIT: usize = 100_000;
|
const DECODE_LIMIT: usize = 100_000;
|
||||||
|
|
||||||
|
|
@ -112,7 +142,7 @@ fn test_container_limits() {
|
||||||
bincode::encode_to_vec(DECODE_LIMIT as u64, bincode::config::standard()).unwrap(),
|
bincode::encode_to_vec(DECODE_LIMIT as u64, bincode::config::standard()).unwrap(),
|
||||||
];
|
];
|
||||||
|
|
||||||
fn validate_fail<T: Decode + 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, _>(
|
let result = bincode::decode_from_slice::<T, _>(
|
||||||
slice,
|
slice,
|
||||||
bincode::config::standard().with_limit::<DECODE_LIMIT>(),
|
bincode::config::standard().with_limit::<DECODE_LIMIT>(),
|
||||||
|
|
@ -134,7 +164,6 @@ fn test_container_limits() {
|
||||||
validate_fail::<VecDeque<i32>>(slice);
|
validate_fail::<VecDeque<i32>>(slice);
|
||||||
validate_fail::<Vec<i32>>(slice);
|
validate_fail::<Vec<i32>>(slice);
|
||||||
validate_fail::<String>(slice);
|
validate_fail::<String>(slice);
|
||||||
validate_fail::<Box<[u8]>>(slice);
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
{
|
{
|
||||||
validate_fail::<std::collections::HashMap<i32, i32>>(slice);
|
validate_fail::<std::collections::HashMap<i32, i32>>(slice);
|
||||||
|
|
@ -142,3 +171,22 @@ fn test_container_limits() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
#[test]
|
||||||
|
fn test_arc_str() {
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
|
let start: Arc<str> = Arc::from("Example String");
|
||||||
|
let mut target = [0u8; 100];
|
||||||
|
let config = bincode::config::standard();
|
||||||
|
|
||||||
|
let len = {
|
||||||
|
let start: Arc<str> = Arc::clone(&start);
|
||||||
|
bincode::encode_into_slice(start, &mut target, config).unwrap()
|
||||||
|
};
|
||||||
|
let slice = &target[..len];
|
||||||
|
|
||||||
|
let decoded: Arc<str> = bincode::borrow_decode_from_slice(slice, config).unwrap().0;
|
||||||
|
assert_eq!(decoded, start);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,65 @@
|
||||||
#![cfg(feature = "atomic")]
|
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use core::sync::atomic::{
|
use core::sync::atomic::Ordering;
|
||||||
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
|
#[cfg(target_has_atomic = "8")]
|
||||||
AtomicU64, AtomicU8, AtomicUsize, Ordering,
|
use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
|
||||||
};
|
#[cfg(target_has_atomic = "16")]
|
||||||
|
use core::sync::atomic::{AtomicI16, AtomicU16};
|
||||||
|
#[cfg(target_has_atomic = "32")]
|
||||||
|
use core::sync::atomic::{AtomicI32, AtomicU32};
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
|
use core::sync::atomic::{AtomicI64, AtomicU64};
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
use core::sync::atomic::{AtomicIsize, AtomicUsize};
|
||||||
use utils::the_same_with_comparer;
|
use utils::the_same_with_comparer;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_atomic_commons() {
|
fn test_atomic_commons() {
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
the_same_with_comparer(AtomicBool::new(true), |a, b| {
|
the_same_with_comparer(AtomicBool::new(true), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
the_same_with_comparer(AtomicBool::new(false), |a, b| {
|
the_same_with_comparer(AtomicBool::new(false), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
the_same_with_comparer(AtomicU8::new(0), |a, b| {
|
the_same_with_comparer(AtomicU8::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "16")]
|
||||||
the_same_with_comparer(AtomicU16::new(0), |a, b| {
|
the_same_with_comparer(AtomicU16::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "32")]
|
||||||
the_same_with_comparer(AtomicU32::new(0), |a, b| {
|
the_same_with_comparer(AtomicU32::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
the_same_with_comparer(AtomicU64::new(0), |a, b| {
|
the_same_with_comparer(AtomicU64::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
the_same_with_comparer(AtomicUsize::new(0), |a, b| {
|
the_same_with_comparer(AtomicUsize::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "8")]
|
||||||
the_same_with_comparer(AtomicI8::new(0), |a, b| {
|
the_same_with_comparer(AtomicI8::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "16")]
|
||||||
the_same_with_comparer(AtomicI16::new(0), |a, b| {
|
the_same_with_comparer(AtomicI16::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "32")]
|
||||||
the_same_with_comparer(AtomicI32::new(0), |a, b| {
|
the_same_with_comparer(AtomicI32::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
the_same_with_comparer(AtomicI64::new(0), |a, b| {
|
the_same_with_comparer(AtomicI64::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
the_same_with_comparer(AtomicIsize::new(0), |a, b| {
|
the_same_with_comparer(AtomicIsize::new(0), |a, b| {
|
||||||
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ fn test_slice() {
|
||||||
assert_eq!(&buffer[..8], &[7, 1, 2, 3, 4, 5, 6, 7]);
|
assert_eq!(&buffer[..8], &[7, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
|
|
||||||
let (output, len): (&[u8], usize) =
|
let (output, len): (&[u8], usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..8], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..8], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 8);
|
assert_eq!(len, 8);
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +151,7 @@ fn test_option_slice() {
|
||||||
assert_eq!(&buffer[..n], &[1, 7, 1, 2, 3, 4, 5, 6, 7]);
|
assert_eq!(&buffer[..n], &[1, 7, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
|
|
||||||
let (output, len): (Option<&[u8]>, usize) =
|
let (output, len): (Option<&[u8]>, usize) =
|
||||||
bincode::decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, n);
|
assert_eq!(len, n);
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ fn test_option_slice() {
|
||||||
assert_eq!(&buffer[..n], &[0]);
|
assert_eq!(&buffer[..n], &[0]);
|
||||||
|
|
||||||
let (output, len): (Option<&[u8]>, usize) =
|
let (output, len): (Option<&[u8]>, usize) =
|
||||||
bincode::decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, n);
|
assert_eq!(len, n);
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +177,7 @@ fn test_str() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (output, len): (&str, usize) =
|
let (output, len): (&str, usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..12], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..12], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 12);
|
assert_eq!(len, 12);
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +193,7 @@ fn test_option_str() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (output, len): (Option<&str>, usize) =
|
let (output, len): (Option<&str>, usize) =
|
||||||
bincode::decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, n);
|
assert_eq!(len, n);
|
||||||
|
|
||||||
|
|
@ -203,7 +203,7 @@ fn test_option_str() {
|
||||||
assert_eq!(&buffer[..n], &[0]);
|
assert_eq!(&buffer[..n], &[0]);
|
||||||
|
|
||||||
let (output, len): (Option<&str>, usize) =
|
let (output, len): (Option<&str>, usize) =
|
||||||
bincode::decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..n], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, n);
|
assert_eq!(len, n);
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +219,7 @@ fn test_array() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (output, len): ([u8; 10], usize) =
|
let (output, len): ([u8; 10], usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..11], bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&buffer[..11], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 11);
|
assert_eq!(len, 11);
|
||||||
|
|
||||||
|
|
@ -234,7 +234,7 @@ fn test_array() {
|
||||||
assert_eq!(&buffer[..9], &[1, 0, 0, 0, 0, 0, 0, 0, 1]);
|
assert_eq!(&buffer[..9], &[1, 0, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
|
||||||
let (output, len): (&[u8], usize) =
|
let (output, len): (&[u8], usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..9], config).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..9], config).unwrap();
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 9);
|
assert_eq!(len, 9);
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +251,7 @@ fn test_duration_out_of_range() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result: Result<(std::time::Duration, usize), _> =
|
let result: Result<(std::time::Duration, usize), _> =
|
||||||
bincode::decode_from_slice(&mut input, bincode::config::standard());
|
bincode::decode_from_slice(&input, bincode::config::standard());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
|
|
@ -274,7 +274,7 @@ fn test_duration_wrapping() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (result, _): (std::time::Duration, _) =
|
let (result, _): (std::time::Duration, _) =
|
||||||
bincode::decode_from_slice(&mut input, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&input, bincode::config::standard()).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.as_secs(), u64::MAX);
|
assert_eq!(result.as_secs(), u64::MAX);
|
||||||
|
|
||||||
|
|
|
||||||
102
tests/derive.rs
102
tests/derive.rs
|
|
@ -20,12 +20,40 @@ fn test_encode() {
|
||||||
assert_eq!(bytes_written, 3);
|
assert_eq!(bytes_written, 3);
|
||||||
assert_eq!(&slice[..bytes_written], &[10, 10, 20]);
|
assert_eq!(&slice[..bytes_written], &[10, 10, 20]);
|
||||||
}
|
}
|
||||||
#[derive(bincode::Decode, PartialEq, Debug, Eq)]
|
#[derive(PartialEq, Debug, Eq)]
|
||||||
pub struct Test2<T> {
|
pub struct Test2<T> {
|
||||||
a: T,
|
a: T,
|
||||||
b: u32,
|
b: u32,
|
||||||
c: u32,
|
c: u32,
|
||||||
}
|
}
|
||||||
|
impl<T> ::bincode::Decode for Test2<T>
|
||||||
|
where
|
||||||
|
T: ::bincode::Decode,
|
||||||
|
{
|
||||||
|
fn decode<D: ::bincode::de::Decoder>(
|
||||||
|
decoder: &mut D,
|
||||||
|
) -> core::result::Result<Self, ::bincode::error::DecodeError> {
|
||||||
|
Ok(Self {
|
||||||
|
a: ::bincode::Decode::decode(decoder)?,
|
||||||
|
b: ::bincode::Decode::decode(decoder)?,
|
||||||
|
c: ::bincode::Decode::decode(decoder)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'__de, T> ::bincode::BorrowDecode<'__de> for Test2<T>
|
||||||
|
where
|
||||||
|
T: ::bincode::BorrowDecode<'__de> + '__de,
|
||||||
|
{
|
||||||
|
fn borrow_decode<D: ::bincode::de::BorrowDecoder<'__de>>(
|
||||||
|
decoder: &mut D,
|
||||||
|
) -> core::result::Result<Self, ::bincode::error::DecodeError> {
|
||||||
|
Ok(Self {
|
||||||
|
a: ::bincode::BorrowDecode::borrow_decode(decoder)?,
|
||||||
|
b: ::bincode::BorrowDecode::borrow_decode(decoder)?,
|
||||||
|
c: ::bincode::BorrowDecode::borrow_decode(decoder)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode() {
|
fn test_decode() {
|
||||||
|
|
@ -62,7 +90,7 @@ fn test_encode_decode_str() {
|
||||||
let len = bincode::encode_into_slice(&start, &mut slice, bincode::config::standard()).unwrap();
|
let len = bincode::encode_into_slice(&start, &mut slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(len, 21);
|
assert_eq!(len, 21);
|
||||||
let (end, len): (Test3, usize) =
|
let (end, len): (Test3, usize) =
|
||||||
bincode::decode_from_slice(&slice[..len], bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&slice[..len], bincode::config::standard()).unwrap();
|
||||||
assert_eq!(end, start);
|
assert_eq!(end, start);
|
||||||
assert_eq!(len, 21);
|
assert_eq!(len, 21);
|
||||||
}
|
}
|
||||||
|
|
@ -83,9 +111,9 @@ fn test_encode_tuple() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_tuple() {
|
fn test_decode_tuple() {
|
||||||
let start = TestTupleStruct(5, 10, 1024);
|
let start = TestTupleStruct(5, 10, 1024);
|
||||||
let mut slice = [5, 10, 251, 0, 4];
|
let slice = [5, 10, 251, 0, 4];
|
||||||
let (result, len): (TestTupleStruct, usize) =
|
let (result, len): (TestTupleStruct, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 5);
|
assert_eq!(len, 5);
|
||||||
}
|
}
|
||||||
|
|
@ -109,9 +137,9 @@ fn test_encode_enum_struct_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_enum_struct_variant() {
|
fn test_decode_enum_struct_variant() {
|
||||||
let start = TestEnum::Bar { name: 5u32 };
|
let start = TestEnum::Bar { name: 5u32 };
|
||||||
let mut slice = [1, 5];
|
let slice = [1, 5];
|
||||||
let (result, len): (TestEnum, usize) =
|
let (result, len): (TestEnum, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 2);
|
assert_eq!(len, 2);
|
||||||
}
|
}
|
||||||
|
|
@ -119,9 +147,9 @@ fn test_decode_enum_struct_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_enum_unit_variant() {
|
fn test_decode_enum_unit_variant() {
|
||||||
let start = TestEnum::Foo;
|
let start = TestEnum::Foo;
|
||||||
let mut slice = [0];
|
let slice = [0];
|
||||||
let (result, len): (TestEnum, usize) =
|
let (result, len): (TestEnum, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 1);
|
assert_eq!(len, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -149,9 +177,9 @@ fn test_encode_enum_tuple_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_enum_tuple_variant() {
|
fn test_decode_enum_tuple_variant() {
|
||||||
let start = TestEnum::Baz(5, 10, 1024);
|
let start = TestEnum::Baz(5, 10, 1024);
|
||||||
let mut slice = [2, 5, 10, 251, 0, 4];
|
let slice = [2, 5, 10, 251, 0, 4];
|
||||||
let (result, len): (TestEnum, usize) =
|
let (result, len): (TestEnum, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 6);
|
assert_eq!(len, 6);
|
||||||
}
|
}
|
||||||
|
|
@ -176,9 +204,9 @@ fn test_encode_borrowed_enum_struct_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_borrowed_enum_struct_variant() {
|
fn test_decode_borrowed_enum_struct_variant() {
|
||||||
let start = TestEnum2::Bar { name: "foo" };
|
let start = TestEnum2::Bar { name: "foo" };
|
||||||
let mut slice = [1, 3, 102, 111, 111];
|
let slice = [1, 3, 102, 111, 111];
|
||||||
let (result, len): (TestEnum2, usize) =
|
let (result, len): (TestEnum2, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 5);
|
assert_eq!(len, 5);
|
||||||
}
|
}
|
||||||
|
|
@ -186,9 +214,9 @@ fn test_decode_borrowed_enum_struct_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_borrowed_enum_unit_variant() {
|
fn test_decode_borrowed_enum_unit_variant() {
|
||||||
let start = TestEnum2::Foo;
|
let start = TestEnum2::Foo;
|
||||||
let mut slice = [0];
|
let slice = [0];
|
||||||
let (result, len): (TestEnum2, usize) =
|
let (result, len): (TestEnum2, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 1);
|
assert_eq!(len, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -216,9 +244,9 @@ fn test_encode_borrowed_enum_tuple_variant() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_borrowed_enum_tuple_variant() {
|
fn test_decode_borrowed_enum_tuple_variant() {
|
||||||
let start = TestEnum2::Baz(5, 10, 1024);
|
let start = TestEnum2::Baz(5, 10, 1024);
|
||||||
let mut slice = [2, 5, 10, 251, 0, 4];
|
let slice = [2, 5, 10, 251, 0, 4];
|
||||||
let (result, len): (TestEnum2, usize) =
|
let (result, len): (TestEnum2, usize) =
|
||||||
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
|
bincode::borrow_decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
||||||
assert_eq!(result, start);
|
assert_eq!(result, start);
|
||||||
assert_eq!(len, 6);
|
assert_eq!(len, 6);
|
||||||
}
|
}
|
||||||
|
|
@ -365,3 +393,45 @@ fn test_enum_with_generics_roundtrip() {
|
||||||
.0;
|
.0;
|
||||||
assert_eq!(start, decoded);
|
assert_eq!(start, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
mod zoxide {
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::borrow::Cow;
|
||||||
|
use bincode::{Decode, Encode};
|
||||||
|
|
||||||
|
pub type Rank = f64;
|
||||||
|
pub type Epoch = u64;
|
||||||
|
|
||||||
|
#[derive(Encode, Decode)]
|
||||||
|
pub struct Dir<'a> {
|
||||||
|
pub path: Cow<'a, str>,
|
||||||
|
pub rank: Rank,
|
||||||
|
pub last_accessed: Epoch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let dirs = &[
|
||||||
|
Dir {
|
||||||
|
path: Cow::Borrowed("Foo"),
|
||||||
|
rank: 1.23,
|
||||||
|
last_accessed: 5,
|
||||||
|
},
|
||||||
|
Dir {
|
||||||
|
path: Cow::Owned(String::from("Bar")),
|
||||||
|
rank: 2.34,
|
||||||
|
last_accessed: 10,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let config = bincode::config::standard();
|
||||||
|
|
||||||
|
let slice = bincode::encode_to_vec(dirs, config).unwrap();
|
||||||
|
let decoded: Vec<Dir> = bincode::borrow_decode_from_slice(&slice, config).unwrap().0;
|
||||||
|
|
||||||
|
assert_eq!(decoded.len(), 2);
|
||||||
|
assert!(matches!(decoded[0].path, Cow::Borrowed("Foo")));
|
||||||
|
assert!(matches!(decoded[1].path, Cow::Borrowed("Bar")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,14 @@ use bincode::{Decode, Encode};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
#[derive(Encode, Decode, PartialEq, Debug)]
|
#[derive(Decode, Encode, PartialEq, Debug)]
|
||||||
|
#[bincode(borrow_decode_bounds = "&'__de U<'a, A>: ::bincode::de::BorrowDecode<'__de> + '__de")]
|
||||||
struct T<'a, A: Clone + Encode + Decode> {
|
struct T<'a, A: Clone + Encode + Decode> {
|
||||||
t: Cow<'a, U<'a, A>>,
|
t: Cow<'a, U<'a, A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Encode, Decode, PartialEq, Debug)]
|
#[derive(Clone, Decode, Encode, PartialEq, Debug)]
|
||||||
|
#[bincode(borrow_decode_bounds = "&'__de A: ::bincode::de::BorrowDecode<'__de> + '__de")]
|
||||||
struct U<'a, A: Clone + Encode + Decode> {
|
struct U<'a, A: Clone + Encode + Decode> {
|
||||||
u: Cow<'a, A>,
|
u: Cow<'a, A>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ impl MemCache {
|
||||||
let encoded = bincode::serde::encode_to_vec(&cache_data, config)?;
|
let encoded = bincode::serde::encode_to_vec(&cache_data, config)?;
|
||||||
let cache_item = CacheItem::new(encoded, expire_seconds);
|
let cache_item = CacheItem::new(encoded, expire_seconds);
|
||||||
|
|
||||||
guard.insert(key.clone(), cache_item);
|
guard.insert(*key, cache_item);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ mod derive {
|
||||||
assert_eq!(len, expected_len);
|
assert_eq!(len, expected_len);
|
||||||
let slice = &slice[..len];
|
let slice = &slice[..len];
|
||||||
let (result, len): (T, usize) =
|
let (result, len): (T, usize) =
|
||||||
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap();
|
bincode::decode_from_slice(slice, bincode::config::standard()).unwrap();
|
||||||
|
|
||||||
assert_eq!(start, result);
|
assert_eq!(start, result);
|
||||||
assert_eq!(len, expected_len);
|
assert_eq!(len, expected_len);
|
||||||
|
|
|
||||||
13
tests/std.rs
13
tests/std.rs
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::blacklisted_name)]
|
||||||
#![cfg(feature = "std")]
|
#![cfg(feature = "std")]
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
@ -89,10 +90,10 @@ fn test_std_commons() {
|
||||||
0,
|
0,
|
||||||
)));
|
)));
|
||||||
the_same_with_comparer(Mutex::new("Hello world".to_string()), |a, b| {
|
the_same_with_comparer(Mutex::new("Hello world".to_string()), |a, b| {
|
||||||
&*a.lock().unwrap() == &*b.lock().unwrap()
|
*a.lock().unwrap() == *b.lock().unwrap()
|
||||||
});
|
});
|
||||||
the_same_with_comparer(RwLock::new("Hello world".to_string()), |a, b| {
|
the_same_with_comparer(RwLock::new("Hello world".to_string()), |a, b| {
|
||||||
&*a.read().unwrap() == &*b.read().unwrap()
|
*a.read().unwrap() == *b.read().unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut map = std::collections::HashMap::new();
|
let mut map = std::collections::HashMap::new();
|
||||||
|
|
@ -128,7 +129,7 @@ fn test_std_commons() {
|
||||||
let cstr = CStr::from_bytes_with_nul(b"Hello world\0").unwrap();
|
let cstr = CStr::from_bytes_with_nul(b"Hello world\0").unwrap();
|
||||||
let len = bincode::encode_into_slice(cstr, &mut buffer, config).unwrap();
|
let len = bincode::encode_into_slice(cstr, &mut buffer, config).unwrap();
|
||||||
let (decoded, len): (CString, usize) =
|
let (decoded, len): (CString, usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
|
bincode::decode_from_slice(&buffer[..len], config).unwrap();
|
||||||
assert_eq!(cstr, decoded.as_c_str());
|
assert_eq!(cstr, decoded.as_c_str());
|
||||||
assert_eq!(len, 12);
|
assert_eq!(len, 12);
|
||||||
|
|
||||||
|
|
@ -136,17 +137,17 @@ fn test_std_commons() {
|
||||||
let path = Path::new("C:/Program Files/Foo");
|
let path = Path::new("C:/Program Files/Foo");
|
||||||
let len = bincode::encode_into_slice(path, &mut buffer, config).unwrap();
|
let len = bincode::encode_into_slice(path, &mut buffer, config).unwrap();
|
||||||
let (decoded, len): (&Path, usize) =
|
let (decoded, len): (&Path, usize) =
|
||||||
bincode::decode_from_slice(&mut buffer[..len], config).unwrap();
|
bincode::borrow_decode_from_slice(&buffer[..len], config).unwrap();
|
||||||
assert_eq!(path, decoded);
|
assert_eq!(path, decoded);
|
||||||
assert_eq!(len, 21);
|
assert_eq!(len, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_system_time_out_of_range() {
|
fn test_system_time_out_of_range() {
|
||||||
let mut input = [0xfd, 0x90, 0x0c, 0xfd, 0xfd, 0x90, 0x0c, 0xfd, 0x90, 0x90];
|
let input = [0xfd, 0x90, 0x0c, 0xfd, 0xfd, 0x90, 0x0c, 0xfd, 0x90, 0x90];
|
||||||
|
|
||||||
let result: Result<(std::time::SystemTime, usize), _> =
|
let result: Result<(std::time::SystemTime, usize), _> =
|
||||||
bincode::decode_from_slice(&mut input, bincode::config::standard());
|
bincode::decode_from_slice(&input, bincode::config::standard());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,10 @@ where
|
||||||
&buffer[..len],
|
&buffer[..len],
|
||||||
core::any::type_name::<C>()
|
core::any::type_name::<C>()
|
||||||
);
|
);
|
||||||
let (decoded, decoded_len): (V, usize) =
|
let (decoded, decoded_len): (V, usize) = bincode::decode_from_slice(&buffer, config).unwrap();
|
||||||
bincode::decode_from_slice(&mut buffer, config).unwrap();
|
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
cmp(&element, &decoded),
|
cmp(element, &decoded),
|
||||||
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
||||||
decoded,
|
decoded,
|
||||||
element,
|
element,
|
||||||
|
|
@ -57,7 +56,7 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
cmp(&element, &decoded),
|
cmp(element, &decoded),
|
||||||
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
||||||
decoded,
|
decoded,
|
||||||
element,
|
element,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue