diff options
Diffstat (limited to 'vendor/camino/src/serde_impls.rs')
-rw-r--r-- | vendor/camino/src/serde_impls.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/vendor/camino/src/serde_impls.rs b/vendor/camino/src/serde_impls.rs index d4c4ecab9..49b6f8621 100644 --- a/vendor/camino/src/serde_impls.rs +++ b/vendor/camino/src/serde_impls.rs @@ -55,3 +55,128 @@ impl Serialize for Utf8Path { self.as_str().serialize(serializer) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::Utf8PathBuf; + use serde_bytes::ByteBuf; + + #[test] + fn valid_utf8() { + let valid_utf8 = &["", "bar", "💩"]; + for input in valid_utf8 { + let encode = Encode { + path: ByteBuf::from(*input), + }; + let encoded = bincode::serialize(&encode).expect("encoded correctly"); + + assert_valid_utf8::<DecodeOwned>(input, &encoded); + assert_valid_utf8::<DecodeBorrowed>(input, &encoded); + } + } + + fn assert_valid_utf8<'de, T: TestTrait<'de>>(input: &str, encoded: &'de [u8]) { + let output = bincode::deserialize::<T>(encoded).expect("valid UTF-8 should be fine"); + assert_eq!( + output.path(), + input, + "for input, with {}, paths should match", + T::description() + ); + } + + #[test] + fn invalid_utf8() { + let invalid_utf8: &[(&[u8], _, _)] = &[ + (b"\xff", 0, 1), + (b"foo\xfe", 3, 1), + (b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9", 4, 1), + ]; + + for (input, valid_up_to, error_len) in invalid_utf8 { + let encode = Encode { + path: ByteBuf::from(*input), + }; + let encoded = bincode::serialize(&encode).expect("encoded correctly"); + + assert_invalid_utf8::<DecodeOwned>(input, &encoded, *valid_up_to, *error_len); + assert_invalid_utf8::<DecodeBorrowed>(input, &encoded, *valid_up_to, *error_len) + } + } + + fn assert_invalid_utf8<'de, T: TestTrait<'de>>( + input: &[u8], + encoded: &'de [u8], + valid_up_to: usize, + error_len: usize, + ) { + let error = bincode::deserialize::<T>(encoded).expect_err("invalid UTF-8 should error out"); + let utf8_error = match *error { + bincode::ErrorKind::InvalidUtf8Encoding(utf8_error) => utf8_error, + other => panic!( + "for input {:?}, with {}, expected ErrorKind::InvalidUtf8Encoding, found: {}", + input, + T::description(), + other + ), + }; + assert_eq!( + utf8_error.valid_up_to(), + valid_up_to, + "for input {:?}, with {}, valid_up_to didn't match", + input, + T::description(), + ); + assert_eq!( + utf8_error.error_len(), + Some(error_len), + "for input {:?}, with {}, error_len didn't match", + input, + T::description(), + ); + } + + #[derive(Serialize, Debug)] + struct Encode { + path: ByteBuf, + } + + trait TestTrait<'de>: Deserialize<'de> + fmt::Debug { + fn description() -> &'static str; + fn path(&self) -> &Utf8Path; + } + + #[derive(Deserialize, Debug)] + #[allow(unused)] + struct DecodeOwned { + path: Utf8PathBuf, + } + + impl<'de> TestTrait<'de> for DecodeOwned { + fn description() -> &'static str { + "DecodeOwned" + } + + fn path(&self) -> &Utf8Path { + &self.path + } + } + + #[derive(Deserialize, Debug)] + #[allow(unused)] + struct DecodeBorrowed<'a> { + #[serde(borrow)] + path: &'a Utf8Path, + } + + impl<'de> TestTrait<'de> for DecodeBorrowed<'de> { + fn description() -> &'static str { + "DecodeBorrowed" + } + + fn path(&self) -> &Utf8Path { + self.path + } + } +} |