9 个版本

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

#345Unix API

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

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