#error #failure #failed #value #native #converting #conversion

failed-result

一个用于将各种失败值转换为具有相应错误类型的结果的精简库

8 个版本

0.2.6 2024 年 7 月 28 日
0.2.5 2023 年 11 月 22 日
0.2.4 2023 年 8 月 27 日
0.2.3 2023 年 4 月 7 日
0.1.0 2022 年 6 月 14 日

#501Rust 模式

Download history 18/week @ 2024-06-30 136/week @ 2024-07-28

136 每月下载量
udbg 中使用

MIT 许可证

8KB
101

failed-result

一个用于将各种失败值转换为具有相应错误类型的结果的精简库

动机

有时,为了实现某些功能,我们必须通过 Rust 中的 FFI 调用原生接口,而原生错误与 Rust 错误之间的转换通常是痛苦的,因此我们需要一种更方便的方式来处理这个问题。

通常,错误类型是 std::io::Error,这对应于每个平台的常见错误类型。

这个包引入了一个特质 LastError,提供了一个方法 LastError::last_error 通过 std::io::Error::last_os_error 获取最后错误,并且它为表示失败结果的通用类型默认实现,例如 bool(false),Option(None),u32(0,Windows 上 BOOL 类型的 FALSE 值) 和任何空指针。

您可以将错误作为 Result 更容易地获取,如下所示

use failed_result::*;

let res = OpenProcess(PROCESS_ALL_ACCESS, 0, 0).last_error();
assert_eq!(res.unwrap_err().kind(), ErrorKind::InvalidInput);

当父函数返回一个 Result 时,这种便利性变得非常显著

fn get_process_path(pid: u32) -> anyhow::Result<String> {
    unsafe {
        let handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid).last_error()?;

        let mut buf = [0u16; MAX_PATH];
        GetModuleFileNameExW(handle, core::ptr::null_mut(), buf.as_mut_ptr(), buf.len() as u32).last_error()?;
        CloseHandle(handle);

        Ok(String::from_utf16(&buf)?)
    }
}

此外,Windows平台还有一个特性 AsHResult,表示根类型为 HRESULT 的结果,您可以使用这个特性轻松地将这些类型转换为 windows::core::Result

我将根据人们的需要实现更多包含其他平台的失败类型,欢迎提出任何反馈。

示例

use failed_result::*;
use std::io::ErrorKind;
use winapi::um::{processthreadsapi::*, winnt::PROCESS_ALL_ACCESS};

unsafe {
    let res = OpenProcess(PROCESS_ALL_ACCESS, 0, 0).last_error();
    assert_eq!(res.unwrap_err().kind(), ErrorKind::InvalidInput);

    let res = OpenProcess(PROCESS_ALL_ACCESS, 0, std::process::id()).last_error();
    assert!(res.is_ok());
}

依赖项

~0–36MB
~527K SLoC