1 个不稳定版本
0.1.0 | 2022年6月26日 |
---|
#2425 在 解析器实现
在 3 个crate中使用(直接使用2个)
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(¤t_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)
}