#source #process #help #file #parsable #origin #load

source-text

从文件或内存字符串中处理 &str,同时跟踪源的帮助上下文

1 个不稳定版本

0.1.0 2023 年 4 月 27 日

#1 in #可解析

MIT 许可证

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