From 42990d82646377028a817c0f6be7cf2e5ce237b4 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Tue, 22 Oct 2019 22:28:21 +0200 Subject: [PATCH 1/2] Deserialize PathBuf from bytes &Path already allows this. Also complete the tests for Path/PathBuf. --- serde/src/de/impls.rs | 18 ++++++++++++++++++ test_suite/tests/test_de.rs | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index e96314809..c1f3dad91 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1580,6 +1580,24 @@ impl<'de> Visitor<'de> for PathBufVisitor { { Ok(From::from(v)) } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + str::from_utf8(v) + .map(From::from) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + String::from_utf8(v) + .map(From::from) + .map_err(|e| Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)) + } } #[cfg(feature = "std")] diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 16628efd6..97ca875c4 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -889,11 +889,23 @@ declare_tests! { Path::new("/usr/local/lib") => &[ Token::BorrowedStr("/usr/local/lib"), ], + Path::new("/usr/local/lib") => &[ + Token::BorrowedBytes(b"/usr/local/lib"), + ], } test_path_buf { + PathBuf::from("/usr/local/lib") => &[ + Token::Str("/usr/local/lib"), + ], PathBuf::from("/usr/local/lib") => &[ Token::String("/usr/local/lib"), ], + PathBuf::from("/usr/local/lib") => &[ + Token::Bytes(b"/usr/local/lib"), + ], + PathBuf::from("/usr/local/lib") => &[ + Token::ByteBuf(b"/usr/local/lib"), + ], } test_cstring { CString::new("abc").unwrap() => &[ From b8772a1e402bb258e5754e3dedd0bf892fcc9124 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Tue, 22 Oct 2019 22:29:30 +0200 Subject: [PATCH 2/2] Deserialize Box through PathBuf::into_boxed_path Including Rc et al. Fixes https://github.com/serde-rs/serde/issues/1633 --- serde/build.rs | 3 ++- serde/src/de/impls.rs | 3 +++ test_suite/tests/test_de.rs | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/serde/build.rs b/serde/build.rs index e36ed62f5..a78b6d79a 100644 --- a/serde/build.rs +++ b/serde/build.rs @@ -29,8 +29,9 @@ fn main() { println!("cargo:rustc-cfg=core_reverse"); } - // CString::into_boxed_c_str stabilized in Rust 1.20: + // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str + // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path if minor >= 20 { println!("cargo:rustc-cfg=de_boxed_c_str"); } diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index c1f3dad91..cffe05900 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1610,6 +1610,9 @@ impl<'de> Deserialize<'de> for PathBuf { } } +#[cfg(all(feature = "std", de_boxed_c_str))] +forwarded_impl!((), Box, PathBuf::into_boxed_path); + //////////////////////////////////////////////////////////////////////////////// // If this were outside of the serde crate, it would just use: diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 97ca875c4..025d87b09 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -907,6 +907,20 @@ declare_tests! { Token::ByteBuf(b"/usr/local/lib"), ], } + test_boxed_path { + PathBuf::from("/usr/local/lib").into_boxed_path() => &[ + Token::Str("/usr/local/lib"), + ], + PathBuf::from("/usr/local/lib").into_boxed_path() => &[ + Token::String("/usr/local/lib"), + ], + PathBuf::from("/usr/local/lib").into_boxed_path() => &[ + Token::Bytes(b"/usr/local/lib"), + ], + PathBuf::from("/usr/local/lib").into_boxed_path() => &[ + Token::ByteBuf(b"/usr/local/lib"), + ], + } test_cstring { CString::new("abc").unwrap() => &[ Token::Bytes(b"abc"),