scolapasta_path/platform_string/
unix_wasi.rs1#![expect(
2 clippy::unnecessary_wraps,
3 reason = "source compatibility with other platforms which may be fallible"
4)]
5
6use std::ffi::{OsStr, OsString};
7#[cfg(unix)]
8use std::os::unix::ffi::{OsStrExt, OsStringExt};
9#[cfg(target_os = "wasi")]
10use std::os::wasi::ffi::{OsStrExt, OsStringExt};
11#[cfg(not(any(unix, target_os = "wasi")))]
12error!("Internal: This module can only be compiled on unix and wasi");
13
14use super::ConvertBytesError;
15
16pub fn bytes_to_os_str(bytes: &[u8]) -> Result<&OsStr, ConvertBytesError> {
17 Ok(OsStr::from_bytes(bytes))
18}
19
20pub fn bytes_to_os_string(bytes: Vec<u8>) -> Result<OsString, ConvertBytesError> {
21 Ok(OsString::from_vec(bytes))
22}
23
24pub fn os_str_to_bytes(os_str: &OsStr) -> Result<&[u8], ConvertBytesError> {
25 Ok(os_str.as_bytes())
26}
27
28pub fn os_string_to_bytes(os_string: OsString) -> Result<Vec<u8>, ConvertBytesError> {
29 Ok(os_string.into_vec())
30}
31
32#[cfg(test)]
33mod tests {
34 use std::ffi::OsString;
35 #[cfg(unix)]
36 use std::os::unix::ffi::OsStringExt;
37 #[cfg(target_os = "wasi")]
38 use std::os::wasi::ffi::OsStringExt;
39 use std::str;
40
41 use super::{bytes_to_os_str, bytes_to_os_string, os_str_to_bytes, os_string_to_bytes};
42
43 #[test]
44 fn utf8_bytes_convert_to_os_str() {
45 let test_cases: &[&[u8]] = &[b"", b"abc", b"abc\0", b"\0abc", b"abc/xyz"];
46 for &bytes in test_cases {
47 bytes_to_os_str(bytes).unwrap();
48 bytes_to_os_string(bytes.to_vec()).unwrap();
49 }
50 }
51
52 #[test]
53 fn invalid_utf8_bytes_convert_to_os_str() {
54 let test_cases: &[&[u8]] = &[b"\xFF", b"\xFE", b"abc/\xFF/\xFE", b"\0\xFF", b"\xFF\0"];
55 for &bytes in test_cases {
56 bytes_to_os_str(bytes).unwrap();
57 bytes_to_os_string(bytes.to_vec()).unwrap();
58 }
59 }
60
61 #[test]
62 fn bytes_os_str_round_trip() {
63 let test_cases: &[&[u8]] = &[b"", b"abc", b"abc\0", b"\0abc", b"abc/xyz"];
64 for &bytes in test_cases {
65 let os_str = bytes_to_os_str(bytes).unwrap();
66 assert_eq!(os_str_to_bytes(os_str).unwrap(), bytes);
67
68 let os_string = bytes_to_os_string(bytes.to_vec()).unwrap();
69 assert_eq!(os_string_to_bytes(os_string).unwrap(), bytes);
70 }
71 }
72
73 #[test]
74 fn invalid_utf8_bytes_os_str_round_trip() {
75 let test_cases: &[&[u8]] = &[b"\xFF", b"\xFE", b"abc/\xFF/\xFE", b"\0\xFF", b"\xFF\0"];
76 for &bytes in test_cases {
77 let os_str = bytes_to_os_str(bytes).unwrap();
78 assert_eq!(os_str_to_bytes(os_str).unwrap(), bytes);
79
80 let os_string = bytes_to_os_string(bytes.to_vec()).unwrap();
81 assert_eq!(os_string_to_bytes(os_string).unwrap(), bytes);
82 }
83 }
84
85 #[test]
86 fn owned_utf8_bytes_convert_to_os_string() {
87 let test_cases: &[&[u8]] = &[b"", b"abc", b"abc\0", b"\0abc", b"abc/xyz"];
88 for &bytes in test_cases {
89 let s = str::from_utf8(bytes).unwrap();
90 let os_string = OsString::from(s.to_owned());
91 os_string_to_bytes(os_string).unwrap();
92 }
93 }
94
95 #[test]
96 fn owned_invalid_utf8_bytes_convert_to_os_string() {
97 let test_cases: &[&[u8]] = &[b"\xFF", b"\xFE", b"abc/\xFF/\xFE", b"\0\xFF", b"\xFF\0"];
98 for &bytes in test_cases {
99 let os_string = OsString::from_vec(bytes.to_owned());
100 os_string_to_bytes(os_string).unwrap();
101 }
102 }
103
104 #[test]
105 fn bytes_os_string_round_trip() {
106 let test_cases: &[&[u8]] = &[b"", b"abc", b"abc\0", b"\0abc", b"abc/xyz"];
107 for &bytes in test_cases {
108 let os_string = bytes_to_os_string(bytes.to_owned()).unwrap();
109 assert_eq!(os_string_to_bytes(os_string).unwrap(), bytes);
110 }
111 }
112
113 #[test]
114 fn invalid_utf8_bytes_os_string_round_trip() {
115 let test_cases: &[&[u8]] = &[b"\xFF", b"\xFE", b"abc/\xFF/\xFE", b"\0\xFF", b"\xFF\0"];
116 for &bytes in test_cases {
117 let os_string = bytes_to_os_string(bytes.to_owned()).unwrap();
118 assert_eq!(os_string_to_bytes(os_string).unwrap(), bytes);
119 }
120 }
121}