9 个版本
0.2.7 | 2022 年 1 月 20 日 |
---|---|
0.2.6 | 2021 年 10 月 18 日 |
0.1.0 | 2021 年 10 月 13 日 |
#345 在 Unix API
579 每月下载
在 stromatekt 中使用
43KB
383 行
unixstring
UnixString
是一个 FFI 友好的空终止字节字符串,可以由 String
、CString
、PathBuf
、OsString
或字节数组构建。
然后可以将 UnixString
转换为 CStr
、Path
或 OsStr
的切片,进行不可失败且无成本的转换操作。
为什么?
UnixString
的目的是在需要使用 FFI(特别是在 Unix 系统上与 C 交互)的任何场景中发挥作用。例如,如果您有一个 PathBuf
,您可以将其数据发送给 libc
函数,如 stat
,但您必须首先分配一个 CString
(或类似的东西)来完成此操作。
同样,对于 OsString
和 String
也是如此,因为这些三种类型允许内部存在零字节,并且不是空终止的。
UnixString 与 CString 非常相似,但具有更高的灵活性和可用性。CString 在实例化后不能更改或增加,而 UnixString 可以通过其 push 和 push_bytes 方法进行扩展,与 OsString 有点相似。
CString 也没有直接引用转换到任何东西,只有 &[u8] 或 &CStr,而 UnixString 则有这些以及更多(下面将描述)。
从 UnixString 获取引用
到 | 函数 | 注意 |
---|---|---|
&CStr |
UnixString::as_c_str |
通过 AsRef 也可用 |
&路径 |
UnixString::as_path |
通过 AsRef 也可用 |
&str |
UnixString::as_str |
如果 UnixString 的字节不是有效的 UTF-8,则失败 |
&[u8] |
UnixString::as_bytes |
返回 UnixString 的字节,不带空终止符 |
&[u8] |
UnixString::as_bytes_with_nul |
返回带有空终止符的 UnixString 的字节 |
&OsStr |
UnixString::as_os_str |
通过 AsRef 也可用 |
* const c_char |
UnixString::as_ptr |
创建 UnixString
从 | 潜在失败 | 特质实现 | 函数 |
---|---|---|---|
CString |
不可失败 | 从 | UnixString::from_cstring |
PathBuf |
如果包含内部零字节则失败 | TryFrom | UnixString::from_pathbuf |
String |
如果包含内部零字节则失败 | TryFrom | UnixString::from_string |
Vec<u8> |
如果包含内部零字节则失败 | TryFrom | UnixString::from_bytes |
OsString |
如果包含内部零字节则失败 | TryFrom | UnixString::from_os_string |
* const c_char |
不安全,请参阅文档获取更多信息 | None | UnixString::from_ptr |
从 UnixString 转换
到 | 函数 | 注意 |
---|---|---|
CString |
UnixString::into_cstring |
|
PathBuf |
UnixString::into_pathbuf |
|
OsString |
UnixString::into_os_string |
|
String |
UnixString::into_string |
如果 UnixString 的字节不是有效的 UTF-8,则失败 |
String |
UnixString::into_string_lossy |
|
String |
UnixString::to_string_lossy |
UnixString::into_string_lossy 的非移动版本 |
String |
UnixString::into_string_unchecked |
不安全:创建一个 String,而不检查字节是否有效 UTF-8 |
Vec<u8> |
UnixString::into_bytes |
返回 UnixString 的字节,不带空终止符 |
Vec<u8> |
UnixString::into_bytes_with_nul |
返回带有空终止符的 UnixString 的字节 |
以上所有操作也可通过 .into() 进行。
示例
使用通过 FFI 收到的字节创建 UnixString
use libc::{c_char, getcwd};
use unixstring::UnixString;
fn main() {
const PATH_SIZ: usize = 1024;
let mut buf: [c_char; 1024] = [0; 1024];
let ptr = &mut buf as *mut c_char;
unsafe { getcwd(ptr, PATH_SIZ) };
if ptr.is_null() {
panic!("getcwd failed");
}
let unix_string = unsafe { UnixString::from_ptr(ptr as *const c_char) };
assert_eq!(unix_string.as_path(), std::env::current_dir().unwrap())
}
使用 UnixString 通过 FFI 发送字节
use std::{convert::TryFrom, env};
use unixstring::UnixString;
fn stat(path: &UnixString) -> std::io::Result<libc::stat> {
// Safety: The all-zero byte-pattern is a valid `struct stat`
let mut stat_buf = unsafe { std::mem::zeroed() };
if -1 == unsafe { libc::lstat(path.as_ptr(), &mut stat_buf) } {
let io_err = std::io::Error::last_os_error();
Err(io_err)
} else {
Ok(stat_buf)
}
}
fn main() -> std::io::Result<()>{
for arg in env::args_os().map(UnixString::try_from).flatten() {
let stat = stat(&arg)?;
let size = stat.st_size;
println!("{} occupies {} bytes.", arg.as_path().display(), size);
}
Ok(())
}
依赖关系
~43KB