mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-26 06:21:02 +00:00
Merge pull request #801 from jonhoo/ffi-strings
impls for null-terminated FFI string types
This commit is contained in:
@@ -25,6 +25,8 @@ use std::net;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::path;
|
use std::path;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -53,6 +55,9 @@ use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor,
|
|||||||
VariantVisitor, Visitor};
|
VariantVisitor, Visitor};
|
||||||
use de::from_primitive::FromPrimitive;
|
use de::from_primitive::FromPrimitive;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use bytes::ByteBuf;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// A visitor that produces a `()`.
|
/// A visitor that produces a `()`.
|
||||||
@@ -295,6 +300,19 @@ impl Deserialize for String {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl Deserialize for CString {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
|
||||||
|
where D: Deserializer
|
||||||
|
{
|
||||||
|
let v: Vec<u8> = try!(ByteBuf::deserialize(deserializer)).into();
|
||||||
|
CString::new(v)
|
||||||
|
.map_err(|e| Error::custom(format!("unexpected NULL at byte {}", e.nul_position())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct OptionVisitor<T> {
|
struct OptionVisitor<T> {
|
||||||
marker: PhantomData<T>,
|
marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ use core::ops;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::path;
|
use std::path;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
use std::ffi::{CString, CStr};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
@@ -98,6 +100,28 @@ impl Serialize for String {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl Serialize for CStr {
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
serializer.serialize_bytes(self.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl Serialize for CString {
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
serializer.serialize_bytes(self.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<T> Serialize for Option<T>
|
impl<T> Serialize for Option<T>
|
||||||
where T: Serialize
|
where T: Serialize
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::net;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@@ -878,6 +879,11 @@ declare_tests! {
|
|||||||
Token::String("/usr/local/lib".to_owned()),
|
Token::String("/usr/local/lib".to_owned()),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_cstring {
|
||||||
|
CString::new("abc").unwrap() => &[
|
||||||
|
Token::Bytes(b"abc"),
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
@@ -995,4 +1001,16 @@ declare_error_tests! {
|
|||||||
],
|
],
|
||||||
Error::Message("invalid length 1, expected an array of length 3".into()),
|
Error::Message("invalid length 1, expected an array of length 3".into()),
|
||||||
}
|
}
|
||||||
|
test_cstring_internal_null<CString> {
|
||||||
|
&[
|
||||||
|
Token::Bytes(b"a\0c"),
|
||||||
|
],
|
||||||
|
Error::Message("unexpected NULL at byte 1".into()),
|
||||||
|
}
|
||||||
|
test_cstring_internal_null_end<CString> {
|
||||||
|
&[
|
||||||
|
Token::Bytes(b"ac\0"),
|
||||||
|
],
|
||||||
|
Error::Message("unexpected NULL at byte 2".into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::net;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
@@ -389,6 +390,16 @@ declare_tests! {
|
|||||||
Token::Str("/usr/local/lib"),
|
Token::Str("/usr/local/lib"),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_cstring {
|
||||||
|
CString::new("abc").unwrap() => &[
|
||||||
|
Token::Bytes(b"abc"),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_cstr {
|
||||||
|
(&*CString::new("abc").unwrap()) => &[
|
||||||
|
Token::Bytes(b"abc"),
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user