1 个不稳定版本
0.1.0 | 2023 年 4 月 27 日 |
---|
#1 in #可解析
11KB
153 行
启用消耗 &str
的 API,以从任何 LoadSource
源检索文本字符串,同时跟踪来源。
术语
此包使用一些术语以帮助区分
- "文本" - 一个将被应用程序代码 "处理" 的
&str
;与用于其他目的的&str
相比,例如用于命名 "文本" 的来源或在错误消息中使用。 - "源" - 一个跟踪
文本
和其来源名称
的 [Source] 值。
示例:[可解析]
假设我们有一个配置文件解析器,它将配置解析到 Config
结构中。我们希望能够解析内存中的字符串或从磁盘加载并解析配置文件,错误消息指示源
use indoc::indoc; // For cleanly formatting test assertions.
use source_text::Parsable;
#[derive(Debug)]
pub struct Config {
// ...
}
impl Parsable for Config {
fn parse_text(text: &str) -> anyhow::Result<Self> {
if text.is_empty() {
Err(anyhow::Error::msg("empty input\n"))
} else {
todo!("implement an `&str` parser...");
}
}
}
let err1 = Config::parse_source("").err().unwrap();
assert_eq!(
format!("{:?}", err1).trim_end(),
indoc! {
r#"
Error in <input>:
Caused by:
empty input
"#
}.trim_end()
);
let configpath = std::path::Path::new("/__this_path_should_not_exist__");
let err2 = Config::parse_source(configpath).err().unwrap();
assert_eq!(
format!("{:?}", err2).trim_end(),
indoc! { r#"
Error in "/__this_path_should_not_exist__":
Caused by:
No such file or directory (os error 2)
"# }.trim_end(),
);
示例:process_text
如果 [可解析] 适合您的使用,您可以使用 [process_text] 包装任何 fn(&str) -> anyhow::Result<T>
use indoc::indoc; // For cleanly formatting test assertions.
fn count_lines<S>(source: S) -> anyhow::Result<usize>
where S: source_text::LoadSource,
{
source_text::process_text(source, |text: &str| {
Ok(text.lines().count())
})
}
fn main() {
let linecount = count_lines("Hello\nWorld!").unwrap();
assert_eq!(2, linecount);
let path = std::path::Path::new("/__this_path_should_not_exist__");
let err = count_lines(path).err().unwrap();
assert_eq!(
format!("{:?}", err).trim_end(),
indoc! { r#"
Error in "/__this_path_should_not_exist__":
Caused by:
No such file or directory (os error 2)
"# }.trim_end(),
);
}
依赖关系
~130KB