[英]How do I turn a glob::GlobError into an io::Error in Rust?
[英]How to include the file path in an IO error in Rust?
在这个极简主义程序中,我希望file_size
函数在Err
包含path /not/there
,以便它可以显示在main
函数中:
use std::fs::metadata;
use std::io;
use std::path::Path;
use std::path::PathBuf;
fn file_size(path: &Path) -> io::Result<u64> {
Ok(metadata(path)?.len())
}
fn main() {
if let Err(err) = file_size(&PathBuf::from("/not/there")) {
eprintln!("{}", err);
}
}
您必须定义自己的错误类型才能包装此附加数据。
就个人而言,我喜欢使用custom_error包,因为它对于处理几种类型特别方便。 在您的情况下,它可能看起来像这样:
use custom_error::custom_error;
use std::fs::metadata;
use std::io;
use std::path::{Path, PathBuf};
use std::result::Result;
custom_error! {ProgramError
Io {
source: io::Error,
path: PathBuf
} = @{format!("{path}: {source}", source=source, path=path.display())},
}
fn file_size(path: &Path) -> Result<u64, ProgramError> {
metadata(path)
.map(|md| md.len())
.map_err(|e| ProgramError::Io {
source: e,
path: path.to_path_buf(),
})
}
fn main() {
if let Err(err) = file_size(&PathBuf::from("/not/there")) {
eprintln!("{}", err);
}
}
输出:
/not/there: No such file or directory (os error 2)
虽然DenysSéguret的答案是正确的,但我喜欢使用我的箱子SNAFU,因为它提供了上下文的概念。 这使得附加路径(或其他任何东西!)的行为非常容易:
use snafu::{ResultExt, Snafu}; // 0.2.3
use std::{
fs, io,
path::{Path, PathBuf},
};
#[derive(Debug, Snafu)]
enum ProgramError {
#[snafu(display("Could not get metadata for {}: {}", path.display(), source))]
Metadata { source: io::Error, path: PathBuf },
}
fn file_size(path: impl AsRef<Path>) -> Result<u64, ProgramError> {
let path = path.as_ref();
let md = fs::metadata(&path).context(Metadata { path })?;
Ok(md.len())
}
fn main() {
if let Err(err) = file_size("/not/there") {
eprintln!("{}", err);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.