blob: c0909bc5a9ea0c30ad4773b8f7e0df92c9bf3966 [file] [log] [blame]
#![allow(dead_code)]
#![warn(unsafe_op_in_unsafe_fn)]
use std::borrow::Cow;
use std::ffi::OsStr;
use std::ffi::OsString;
#[cfg(feature = "raw_os_str")]
use std::mem;
use std::path::Path;
use std::path::PathBuf;
use std::result;
use os_str_bytes::EncodingError;
use os_str_bytes::OsStrBytes;
use os_str_bytes::OsStringBytes;
#[cfg(feature = "raw_os_str")]
use os_str_bytes::RawOsStr;
pub(crate) type Result<T> = result::Result<T, EncodingError>;
pub(crate) const WTF8_STRING: &[u8] = b"foo\xED\xA0\xBD\xF0\x9F\x92\xA9bar";
// SAFETY: This string is valid in WTF-8.
#[cfg(all(any(unix, windows), feature = "raw_os_str"))]
pub(crate) const RAW_WTF8_STRING: &RawOsStr =
unsafe { from_raw_bytes_unchecked(WTF8_STRING) };
#[cfg(feature = "raw_os_str")]
pub(crate) const unsafe fn from_raw_bytes_unchecked(
string: &[u8],
) -> &RawOsStr {
// SAFETY: This implementation detail can only be assumed by this crate.
unsafe { mem::transmute(string) }
}
#[track_caller]
fn test_from_bytes<'a, T, U, S>(result: &Result<U>, string: S)
where
S: Into<Cow<'a, [u8]>>,
T: 'a + AsRef<OsStr> + OsStrBytes + ?Sized,
U: AsRef<OsStr>,
{
assert_eq!(
result.as_ref().map(AsRef::as_ref),
T::from_raw_bytes(string).as_deref().map(AsRef::as_ref),
);
}
pub(crate) fn from_bytes(string: &[u8]) -> Result<Cow<'_, OsStr>> {
let os_string = OsStr::from_raw_bytes(string);
test_from_bytes::<Path, _, _>(&os_string, string);
os_string
}
pub(crate) fn from_vec(string: Vec<u8>) -> Result<OsString> {
let os_string = OsString::from_raw_vec(string.clone());
test_from_bytes::<OsStr, _, _>(&os_string, string.clone());
let path = PathBuf::from_raw_vec(string.clone());
test_from_bytes::<Path, _, _>(&path, string);
assert_eq!(os_string, path.map(PathBuf::into_os_string));
os_string
}
pub(crate) fn test_bytes(string: &[u8]) -> Result<()> {
let os_string = from_bytes(string)?;
assert_eq!(string.len(), os_string.len());
assert_eq!(string, &*os_string.to_raw_bytes());
Ok(())
}
pub(crate) fn test_vec(string: &[u8]) -> Result<()> {
let os_string = from_vec(string.to_owned())?;
assert_eq!(string.len(), os_string.len());
assert_eq!(string, os_string.into_raw_vec());
Ok(())
}
pub(crate) fn test_utf8_bytes(string: &str) {
let os_string = OsStr::new(string);
let string = string.as_bytes();
assert_eq!(Ok(Cow::Borrowed(os_string)), from_bytes(string));
assert_eq!(string, &*os_string.to_raw_bytes());
}
pub(crate) fn test_utf8_vec(string: &str) {
let os_string = string.to_owned().into();
let string = string.as_bytes();
assert_eq!(Ok(&os_string), from_vec(string.to_owned()).as_ref());
assert_eq!(string, os_string.into_raw_vec());
}