#header #header-parser #markdown-parser #format #file #path #simplifies

header-parsing

简化解析受 Markdown 启发的文件格式的标题

1 个不稳定版本

0.1.0 2022年6月26日

#2425解析器实现


3 个crate中使用(直接使用2个)

MIT/Apache

5KB

标题解析

这个库旨在帮助解析以“#”标记标题的受 Markdown 启发的文件。

仅有的一个函数 parse_header 用于逐行解析文件。如果行以“#”开头,该函数将返回 Some bool 表示格式有效,否则返回 None

唯一无效的格式是当标题开始时比上一个标题多一个“#”。

这使得使用 Markdown 作为配置文件变得可行。

示例配置

标题和子标题存储为数组。

例如,您可以有一个这样的文件

A

# Header 1

B

## Subheader 1

C

## Subheader 2

D

# Header 2

E

## Subheader 1

F

## Subheader 2

G

字母属于不同的标题

  • A 不属于任何子标题 ([])
  • B 属于 "Header 1" (["Header 1"])
  • C 属于 "Header 1" 的 "Subheader 1" (["Header 1", "Subheader 1"])
  • D 属于 "Header 1" 的 "Subheader 2" (["Header 1", "Subheader 2"])
  • E 属于 "Header 2" (["Header 2"])
  • F 属于 "Header 2" 的 "子标题 1" (["Header 2", "子标题 1"])
  • G 属于 "Header 2" 的 "子标题 2" (["Header 2", "子标题 2"])

用法

您必须自己存储标题和子标题的路径。这样,您可以按自己的意愿处理标题之间的部分。

use header_parsing::parse_header;

use std::io::{BufRead, BufReader, Read};

enum Error {
    SubheaderWithoutHeader,
    ... // Custom error types
}

fn parse<R: Read>(reader: R) -> Result<Map, Error> {
    // a Vec<String>
    let mut current_path = Vec::new();
    // probably some map, like be a HashMap<Vec<String>, Value>
    let mut result = Map::new();
    // the content inbetween the headers parsed into the wanted format
    let mut value = Value::new();

    for line in BufReader::new(reader).lines() {
        if let Ok(line) = line {
            // if current line is a header
            if let Some(success) = parse_header(&current_path, &line) {
                if let Ok(path_changes) = success {
                    // add parsed value to previous subheader
                    result.add(current_path.clone(), value);
                    // start parsing next subsection
                    value = Value::new();
                    // apply path changes
                    path_changes.apply(&mut current_path);
                } else {
                    return Err(Error::SubheaderWithoutHeader);
                }
            }
        } else {
            // parse the content inbetween headers
            value.add_and_parse_line(line)?;
        }
    }

    result.add(value);

    Ok(result)
}

无运行时依赖