Merge pull request #811 from jonhoo/deserialize-cstr

Add Deserialize impl for CStr
This commit is contained in:
David Tolnay 2017-03-08 21:06:09 -08:00 committed by GitHub
commit 6750fdaae1
8 changed files with 64 additions and 64 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

@ -5,7 +5,7 @@ authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
publish = false publish = false
[features] [features]
unstable-testing = ["compiletest_rs"] unstable = ["serde/unstable", "compiletest_rs"]
[dev-dependencies] [dev-dependencies]
fnv = "1.0" fnv = "1.0"

View File

@ -1,4 +1,4 @@
#![cfg(feature = "unstable-testing")] #![cfg(feature = "unstable")]
extern crate compiletest_rs as compiletest; extern crate compiletest_rs as compiletest;

View File

@ -1,3 +1,5 @@
#![cfg_attr(feature = "unstable", feature(into_boxed_c_str))]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
@ -8,6 +10,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,15 +891,44 @@ 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() {
assert_de_tokens( assert_de_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(), &"1.2.3.4".parse::<net::IpAddr>().unwrap(),
&[Token::Str("1.2.3.4")], &[Token::Str("1.2.3.4")],
); );
} }
#[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> {
&[ &[

View File

@ -2,7 +2,7 @@
// successfully when there are a variety of generics and non-(de)serializable // successfully when there are a variety of generics and non-(de)serializable
// types involved. // types involved.
#![cfg_attr(feature = "unstable-testing", feature(non_ascii_idents))] #![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
@ -220,8 +220,8 @@ fn test_gen() {
} }
assert::<EmptyEnumVariant>(); assert::<EmptyEnumVariant>();
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
struct NonAsciiIdents { struct NonAsciiIdents {
σ: f64 σ: f64
} }
@ -246,12 +246,12 @@ fn test_gen() {
f: u8, f: u8,
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
struct EmptyTuple(); struct EmptyTuple();
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
struct EmptyTupleDenyUnknown(); struct EmptyTupleDenyUnknown();
@ -276,8 +276,8 @@ fn test_gen() {
Variant, Variant,
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
enum EmptyVariants { enum EmptyVariants {
Braced {}, Braced {},
Tuple(), Tuple(),
@ -288,8 +288,8 @@ fn test_gen() {
TupleSkip(#[serde(skip_deserializing)] u8), TupleSkip(#[serde(skip_deserializing)] u8),
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
enum EmptyVariantsDenyUnknown { enum EmptyVariantsDenyUnknown {
Braced {}, Braced {},

View File

@ -21,9 +21,6 @@ use self::serde_test::{
extern crate fnv; extern crate fnv;
use self::fnv::FnvHasher; use self::fnv::FnvHasher;
#[cfg(feature = "unstable")]
use serde::ser::iterator;
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -402,54 +399,11 @@ declare_tests! {
} }
} }
#[cfg(feature = "unstable")]
#[test]
fn test_iterator() {
assert_ser_tokens(iterator([0; 0].iter()), &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter()), &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter().map(|x| x * 2)), &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(4),
Token::SeqSep,
Token::I32(6),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter().filter(|&x| x % 2 != 0)), &[
Token::SeqStart(None),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
]);
}
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[test] #[test]
fn test_net_ipaddr() { fn test_net_ipaddr() {
assert_ser_tokens( assert_ser_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(), &"1.2.3.4".parse::<net::IpAddr>().unwrap(),
&[Token::Str("1.2.3.4")], &[Token::Str("1.2.3.4")],
); );
} }

View File

@ -30,7 +30,7 @@ if [ -n "${CLIPPY}" ]; then
cargo clippy --features unstable-testing -- -Dclippy cargo clippy --features unstable-testing -- -Dclippy
cd "$DIR/test_suite" cd "$DIR/test_suite"
cargo clippy --features unstable-testing -- -Dclippy cargo clippy --features unstable -- -Dclippy
cd "$DIR/test_suite/no_std" cd "$DIR/test_suite/no_std"
cargo clippy -- -Dclippy cargo clippy -- -Dclippy
@ -46,7 +46,7 @@ else
cd "$DIR/test_suite/deps" cd "$DIR/test_suite/deps"
channel build channel build
cd "$DIR/test_suite" cd "$DIR/test_suite"
channel test --features unstable-testing channel test --features unstable
cd "$DIR/test_suite/no_std" cd "$DIR/test_suite/no_std"
channel build channel build