9 个版本

0.2.7 2022 年 1 月 20 日
0.2.6 2021 年 10 月 18 日
0.1.0 2021 年 10 月 13 日

#345Unix API

Download history • Rust 包仓库 92/week @ 2024-04-21 • Rust 包仓库 196/week @ 2024-04-28 • Rust 包仓库 142/week @ 2024-05-05 • Rust 包仓库 81/week @ 2024-05-12 • Rust 包仓库 224/week @ 2024-05-19 • Rust 包仓库 162/week @ 2024-05-26 • Rust 包仓库 44/week @ 2024-06-02 • Rust 包仓库 236/week @ 2024-06-09 • Rust 包仓库 98/week @ 2024-06-16 • Rust 包仓库 63/week @ 2024-06-23 • Rust 包仓库 70/week @ 2024-06-30 • Rust 包仓库 42/week @ 2024-07-07 • Rust 包仓库 39/week @ 2024-07-14 • Rust 包仓库 211/week @ 2024-07-21 • Rust 包仓库 104/week @ 2024-07-28 • Rust 包仓库 223/week @ 2024-08-04 • Rust 包仓库

579 每月下载
stromatekt 中使用

MIT 许可证

43KB
383

unixstring codecov Crates.io Docs

UnixString 是一个 FFI 友好的空终止字节字符串,可以由 StringCStringPathBufOsString 或字节数组构建。

然后可以将 UnixString 转换为 CStrPathOsStr 的切片,进行不可失败且无成本的转换操作。

为什么?

UnixString 的目的是在需要使用 FFI(特别是在 Unix 系统上与 C 交互)的任何场景中发挥作用。例如,如果您有一个 PathBuf,您可以将其数据发送给 libc 函数,如 stat,但您必须首先分配一个 CString(或类似的东西)来完成此操作。

同样,对于 OsStringString 也是如此,因为这些三种类型允许内部存在零字节,并且不是空终止的。

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