Rust元数据解析库gray_matter的使用,gray_matter可高效提取和解析Markdown、YAML等文件中的Front Matter数据
Rust元数据解析库gray_matter的使用
gray_matter是一个高效的Rust库,用于从Markdown、YAML等文件中提取和解析Front Matter数据。它是gray-matter的Rust实现版本,支持以下格式的Front Matter解析:
- TOML
- YAML
- JSON
该库还提供了Engine
trait接口,允许开发者实现自定义的解析器。
基础用法
添加依赖
首先需要在Cargo.toml中添加依赖:
[dependencies]
gray_matter = "0.3"
基本解析示例
use gray_matter::{Matter, ParsedEntity, Result};
use gray_matter::engine::YAML;
use serde::Deserialize;
const INPUT: &str = r#"---
title: gray-matter-rs
tags:
- gray-matter
- rust
---
Some excerpt
---
Other stuff
"#;
fn main() -> Result<()> {
// 使用YAML引擎创建解析器
let matter = Matter::<YAML>::new();
let result: ParsedEntity = matter.parse(INPUT)?;
// 验证解析结果
assert_eq!(result.content, "Some excerpt\n---\nOther stuff");
assert_eq!(result.excerpt, Some("Some excerpt".to_owned()));
assert_eq!(result.data.as_ref().unwrap()["title"].as_string(), Ok("gray-matter-rs".to_string()));
assert_eq!(result.data.as_ref().unwrap()["tags"][0].as_string(), Ok("gray-matter".to_string()));
assert_eq!(result.data.as_ref().unwrap()["tags"][1].as_string(), Ok("rust".to_string()));
// 将数据反序列化为自定义结构体
#[derive(Deserialize, Debug)]
struct FrontMatter {
title: String,
tags: Vec<String>
}
let result_with_struct = matter.parse::<FrontMatter>(INPUT)?;
println!("{:?}", result_with_struct.data);
// 输出: FrontMatter { title: "gray-matter-rs", tags: ["gray-matter", "rust"] }
Ok(())
}
自定义分隔符
use gray_matter::{Matter, ParsedEntity, Result};
use gray_matter::engine::YAML;
use serde::Deserialize;
fn main() -> Result<()> {
let mut matter: Matter<YAML> = Matter::new();
// 设置自定义分隔符
matter.delimiter = "~~~".to_owned();
matter.excerpt_delimiter = Some("<!-- endexcerpt -->".to_owned());
#[derive(Deserialize, Debug)]
struct FrontMatter {
abc: String,
}
let result: ParsedEntity<FrontMatter> = matter.parse(
"~~~\nabc: xyz\n~~~\nfoo\nbar\nbaz\n<!-- endexcerpt -->\ncontent",
)?;
Ok(())
}
自定义关闭分隔符
use gray_matter::{Matter, ParsedEntity, Result};
use gray_matter::engine::YAML;
use serde::Deserialize;
fn main() -> Result<()> {
let mut matter: Matter<YAML> = Matter::new();
// 设置自定义打开和关闭分隔符
matter.delimiter = "<!--".to_owned();
matter.close_delimiter = Some("-->".to_owned());
matter.excerpt_delimiter = Some("<!-- endexcerpt -->".to_owned());
#[derive(Deserialize, Debug)]
struct FrontMatter {
abc: String,
}
let result: ParsedEntity<FrontMatter> = matter.parse(
"<!--\nabc: xyz\n-->\nfoo\nbar\nbaz\n<!-- endexcerpt -->\ncontent",
)?;
Ok(())
}
完整示例
下面是一个完整的Markdown文件解析示例:
use gray_matter::{Matter, ParsedEntity, Result};
use gray_matter::engine::YAML;
use serde::Deserialize;
fn main() -> Result<()> {
// 包含Front Matter的Markdown内容
const MARKDOWN: &str = r#"---
title: Rust元数据解析
author: 张伟
date: 2023-05-15
categories:
- 编程
- Rust
---
这是文章的摘要部分
<!-- endexcerpt -->
这里是文章的正文内容..."#;
// 创建解析器并配置分隔符
let mut matter = Matter::<YAML>::new();
matter.delimiter = "---".to_owned();
matter.close_delimiter = Some("---".to_owned());
matter.excerpt_delimiter = Some("<!-- endexcerpt -->".to_owned());
// 定义Front Matter数据结构
#[derive(Deserialize, Debug)]
struct ArticleMeta {
title: String,
author: String,
date: String,
categories: Vec<String>,
}
// 解析内容
let result = matter.parse::<ArticleMeta>(MARKDOWN)?;
// 输出解析结果
println!("元数据: {:?}", result.data.unwrap());
println!("正文内容: {}", result.content);
println!("摘要: {}", result.excerpt.unwrap());
Ok(())
}
这个完整示例展示了如何:
- 配置gray_matter解析器
- 定义自定义数据结构来反序列化Front Matter
- 解析包含Front Matter的Markdown内容
- 提取并输出元数据、正文和摘要
你可以根据需要调整解析引擎(TOML/JSON/YAML)或修改分隔符配置以适应不同的文档格式。
1 回复
以下是基于您提供的内容整理的完整示例代码,包含了gray_matter库的主要使用场景:
完整示例代码
// 导入所需库
use gray_matter::{Matter, engine::{YAML, TOML, JSON}};
use serde::Deserialize;
use std::fs;
// 定义用于反序列化的结构体
#[derive(Debug, Deserialize)]
struct Article {
title: String,
author: String,
date: String,
tags: Vec<String>,
draft: bool,
}
fn main() {
// 示例1:基本YAML解析
let matter = Matter::<YAML>::new();
let content = r#"---
title: Rust编程入门
author: 张伟
date: 2023-08-15
tags: [rust, 编程, 教程]
draft: false
---
这是文章正文内容..."#;
let result = matter.parse(content);
println!("[示例1] 元数据: {:?}", result.data);
println!("[示例1] 内容: {}\n", result.content);
// 示例2:反序列化为结构体
let result = matter.parse_with_struct::<Article>(content).unwrap();
let article = result.data.unwrap();
println!("[示例2] 标题: {}", article.title);
println!("[示例2] 作者: {}", article.author);
println!("[示例2] 标签: {:?}\n", article.tags);
// 示例3:处理TOML格式
let matter_toml = Matter::<TOML>::new();
let toml_content = r#"+++
title = "TOML格式示例"
+++
正文内容..."#;
let result = matter_toml.parse(toml_content);
println!("[示例3] TOML解析结果: {:?}\n", result.data);
// 示例4:自定义分隔符
let mut custom_matter = Matter::<YAML>::new();
custom_matter.delimiter = Some("/* * */".to_string());
let custom_content = r#"/* * */
title: 自定义分隔符
/* * */
正文..."#;
let result = custom_matter.parse(custom_content);
println!("[示例4] 自定义分隔符结果: {:?}\n", result.data);
// 示例5:从文件读取
if let Ok(file_content) = fs::read_to_string("example.md") {
let result = matter.parse(&file_content);
println!("[示例5] 文件解析结果 - 元数据: {:?}", result.data);
println!("[示例5] 文件解析结果 - 内容长度: {}\n", result.content.len());
} else {
println!("[示例5] 未找到example.md文件\n");
}
// 示例6:处理无Front Matter的内容
let no_frontmatter = "纯文本内容,没有元数据";
let result = matter.parse(no_frontmatter);
println!("[示例6] 无FrontMatter时data是否为None: {}", result.data.is_none());
println!("[示例6] 内容保持不变: {}\n", result.content == no_frontmatter);
}
示例说明
这个完整示例演示了gray_matter库的6个主要使用场景:
- 基本YAML解析:解析包含YAML格式Front Matter的字符串
- 反序列化为结构体:将元数据解析到自定义的Rust结构体
- 处理TOML格式:展示如何使用不同的解析引擎
- 自定义分隔符:修改默认的分隔符配置
- 从文件读取:读取并解析文件内容
- 无Front Matter内容:处理没有元数据的纯文本内容
每个示例都有清晰的输出标记,方便理解每个功能的实际效果。使用时需要根据实际情况:
- 创建相应的Markdown文件(如example.md)
- 添加适当的Cargo.toml依赖
- 调整结构体定义以匹配您的元数据格式