Add Deserialize impl for CStr

Fixes #810
This commit is contained in:
Jon Gjengset 2017-03-08 23:13:28 -05:00
parent a4ee9bd045
commit 0c2fed49e2
No known key found for this signature in database
GPG Key ID: D64AC9D67176DC71
3 changed files with 45 additions and 1 deletions

View File

@ -27,6 +27,8 @@ use std::path;
use core::str; use core::str;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::ffi::CString; use std::ffi::CString;
#[cfg(all(feature = "std", feature="unstable"))]
use std::ffi::CStr;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::rc::Rc; use std::rc::Rc;
@ -300,6 +302,16 @@ impl Deserialize for String {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", feature="unstable"))]
impl Deserialize for Box<CStr> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer
{
let s = try!(CString::deserialize(deserializer));
Ok(s.into_boxed_c_str())
}
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl Deserialize for CString { impl Deserialize for CString {
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error> fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>

View File

@ -61,7 +61,7 @@
#![doc(html_root_url="https://docs.serde.rs")] #![doc(html_root_url="https://docs.serde.rs")]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "unstable", feature(inclusive_range, nonzero, specialization, zero_one))] #![cfg_attr(feature = "unstable", feature(inclusive_range, nonzero, specialization, zero_one, into_boxed_c_str))]
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))] #![cfg_attr(feature = "collections", feature(collections))]
#![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] #![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))]

View File

@ -8,6 +8,9 @@ use std::time::Duration;
use std::default::Default; use std::default::Default;
use std::ffi::CString; use std::ffi::CString;
#[cfg(feature = "unstable")]
use std::ffi::CStr;
extern crate serde; extern crate serde;
use serde::Deserialize; use serde::Deserialize;
@ -886,6 +889,13 @@ declare_tests! {
} }
} }
#[cfg(feature = "unstable")]
#[test]
fn test_cstr() {
assert_de_tokens::<Box<CStr>>(&CString::new("abc").unwrap().into_boxed_c_str(),
&[Token::Bytes(b"abc")]);
}
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[test] #[test]
fn test_net_ipaddr() { fn test_net_ipaddr() {
@ -895,6 +905,28 @@ fn test_net_ipaddr() {
); );
} }
#[cfg(feature = "unstable")]
#[test]
fn test_cstr_internal_null() {
assert_de_tokens_error::<Box<CStr>>(
&[
Token::Bytes(b"a\0c"),
],
Error::Message("nul byte found in provided data at position: 1".into())
);
}
#[cfg(feature = "unstable")]
#[test]
fn test_cstr_internal_null_end() {
assert_de_tokens_error::<Box<CStr>>(
&[
Token::Bytes(b"ac\0"),
],
Error::Message("nul byte found in provided data at position: 2".into())
);
}
declare_error_tests! { declare_error_tests! {
test_unknown_field<StructDenyUnknown> { test_unknown_field<StructDenyUnknown> {
&[ &[