mirror of https://git.sr.ht/~stygianentity/bincode
Added support for CStr and CString
This commit is contained in:
parent
a322e0f1b3
commit
33dd4f761d
|
|
@ -71,6 +71,13 @@ pub enum DecodeError {
|
|||
/// The length of the array found in the binary format.
|
||||
found: usize,
|
||||
},
|
||||
|
||||
/// The decoder tried to decode a `CStr` or `CString`, but the incoming data contained a 0 byte
|
||||
#[cfg(feature = "std")]
|
||||
CStrNulError {
|
||||
/// The inner exception
|
||||
inner: std::ffi::FromBytesWithNulError,
|
||||
},
|
||||
}
|
||||
|
||||
/// Integer types. Used by [DecodeError]. These types have no purpose other than being shown in errors.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use crate::{
|
||||
config::{self, Config},
|
||||
de::{read::Reader, Decodable, Decoder},
|
||||
enc::{write::Writer, Encodeable, Encoder},
|
||||
de::{read::Reader, BorrowDecodable, BorrowDecode, Decodable, Decode, Decoder},
|
||||
enc::{write::Writer, Encode, Encodeable, Encoder},
|
||||
error::{DecodeError, EncodeError},
|
||||
};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
/// Decode type `D` from the given reader. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`.
|
||||
pub fn decode_from<D: Decodable, R: std::io::Read>(src: &mut R) -> Result<D, DecodeError> {
|
||||
|
|
@ -71,3 +72,36 @@ impl<'storage, W: std::io::Write> Writer for IoWriter<'storage, W> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Encodeable for &'a CStr {
|
||||
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
|
||||
self.to_bytes_with_nul().encode(encoder)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> BorrowDecodable<'de> for &'de CStr {
|
||||
fn borrow_decode<D: BorrowDecode<'de>>(decoder: D) -> Result<Self, DecodeError> {
|
||||
let bytes = <&[u8]>::borrow_decode(decoder)?;
|
||||
CStr::from_bytes_with_nul(bytes).map_err(|e| DecodeError::CStrNulError { inner: e })
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodeable for CString {
|
||||
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
|
||||
self.as_bytes_with_nul().encode(encoder)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for CString {
|
||||
fn decode<D: Decode>(decoder: D) -> Result<Self, DecodeError> {
|
||||
// BlockedTODO: https://github.com/rust-lang/rust/issues/73179
|
||||
// use `from_vec_with_nul` instead, combined with:
|
||||
// let bytes = std::vec::Vec::<u8>::decode(decoder)?;
|
||||
|
||||
// now we have to allocate twice unfortunately
|
||||
let vec: std::vec::Vec<u8> = std::vec::Vec::decode(decoder)?;
|
||||
let cstr =
|
||||
CStr::from_bytes_with_nul(&vec).map_err(|e| DecodeError::CStrNulError { inner: e })?;
|
||||
Ok(cstr.into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
tests/std.rs
18
tests/std.rs
|
|
@ -1,5 +1,9 @@
|
|||
#![cfg(feature = "std")]
|
||||
|
||||
mod utils;
|
||||
|
||||
use utils::the_same;
|
||||
|
||||
struct Foo {
|
||||
pub a: u32,
|
||||
pub b: u32,
|
||||
|
|
@ -49,3 +53,17 @@ fn test_std_file() {
|
|||
assert_eq!(foo.a, 30);
|
||||
assert_eq!(foo.b, 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_std_commons() {
|
||||
use std::ffi::{CStr, CString};
|
||||
the_same(CString::new("Hello world").unwrap());
|
||||
|
||||
let config = bincode::config::Default;
|
||||
let cstr = CStr::from_bytes_with_nul(b"Hello world\0").unwrap();
|
||||
let mut buffer = [0u8; 1024];
|
||||
let len = bincode::encode_into_slice_with_config(cstr, &mut buffer, config).unwrap();
|
||||
let decoded: &CStr = bincode::decode_with_config(&mut buffer[..len], config).unwrap();
|
||||
|
||||
assert_eq!(cstr, decoded);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ use core::fmt::Debug;
|
|||
|
||||
fn the_same_with_config<V, C>(element: V, config: C)
|
||||
where
|
||||
V: bincode::enc::Encodeable
|
||||
+ for<'de> bincode::de::Decodable
|
||||
+ PartialEq
|
||||
+ Debug
|
||||
+ Clone
|
||||
+ 'static,
|
||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
||||
C: Config,
|
||||
{
|
||||
let mut buffer = [0u8; 1024];
|
||||
|
|
@ -26,12 +21,7 @@ where
|
|||
|
||||
pub fn the_same<V>(element: V)
|
||||
where
|
||||
V: bincode::enc::Encodeable
|
||||
+ for<'de> bincode::de::Decodable
|
||||
+ PartialEq
|
||||
+ Debug
|
||||
+ Clone
|
||||
+ 'static,
|
||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
||||
{
|
||||
// A matrix of each different config option possible
|
||||
the_same_with_config(
|
||||
|
|
|
|||
Loading…
Reference in New Issue