Add source and test files.
This commit is contained in:
parent
5b6c33bccd
commit
69778bbfa6
|
@ -0,0 +1,71 @@
|
|||
/*!
|
||||
# toml-frontmatter
|
||||
|
||||
> **TOML frontmatter parser.**
|
||||
|
||||
See the [`parse`] documentation for an example.
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the [Apache License 2.0](https://spdx.org/licenses/Apache-2.0.html) and [MIT](https://spdx.org/licenses/MIT.html) licenses, see [LICENSE-Apache](https://git.bauke.xyz/Holllo/toml-frontmatter/src/branch/main/LICENSE-Apache) and [LICENSE-MIT](https://git.bauke.xyz/Holllo/toml-frontmatter/src/branch/main/LICENSE-MIT) for more information.
|
||||
*/
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs, clippy::missing_docs_in_private_items)]
|
||||
|
||||
use {
|
||||
anyhow::{anyhow, Result},
|
||||
serde::Deserialize,
|
||||
};
|
||||
|
||||
/**
|
||||
Parse a struct that implements [`serde::Deserialize`] from frontmatter and
|
||||
return the remaining contents of the string.
|
||||
|
||||
## Errors
|
||||
|
||||
This function will return an [`Err`] when:
|
||||
|
||||
- the data doesn't have a frontmatter section,
|
||||
- the frontmatter isnt' at the beginning of the data.
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Frontmatter {
|
||||
date: String,
|
||||
}
|
||||
|
||||
let sample = r#"
|
||||
---toml
|
||||
date = "2023-01-01"
|
||||
---
|
||||
|
||||
Some **Markdown**. Or something else!
|
||||
"#.trim();
|
||||
|
||||
let (frontmatter, markdown) = toml_frontmatter::parse::<Frontmatter>(sample).unwrap();
|
||||
```
|
||||
*/
|
||||
pub fn parse<'a, D: Deserialize<'a>>(data: &'a str) -> Result<(D, &'a str)> {
|
||||
let start_marker = "---toml\n";
|
||||
let end_marker = "\n---\n";
|
||||
|
||||
let (start, end) = match (data.find(start_marker), data.find(end_marker)) {
|
||||
(Some(start), Some(end)) => (start, end),
|
||||
_ => return Err(anyhow!("Missing frontmatter")),
|
||||
};
|
||||
|
||||
if start != 0 {
|
||||
return Err(anyhow!("Frontmatter not at beginning of data"));
|
||||
}
|
||||
|
||||
let start = start + start_marker.len();
|
||||
let frontmatter = &data[start..end];
|
||||
|
||||
let end = end + end_marker.len();
|
||||
let extra = &data[end..];
|
||||
|
||||
Ok((toml::from_str::<D>(frontmatter)?, extra.trim_start()))
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#[test]
|
||||
#[should_panic(expected = "Missing frontmatter")]
|
||||
fn test_missing_frontmatter() {
|
||||
toml_frontmatter::parse::<()>("# Heading").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Frontmatter not at beginning of data")]
|
||||
fn test_frontmatter_not_at_start() {
|
||||
let sample = r#"
|
||||
# Heading
|
||||
|
||||
---toml
|
||||
date = "2023-01-01"
|
||||
---
|
||||
|
||||
Text."#;
|
||||
|
||||
toml_frontmatter::parse::<()>(sample).unwrap();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
use {
|
||||
anyhow::Result,
|
||||
insta::{assert_snapshot, assert_toml_snapshot},
|
||||
serde::{Deserialize, Serialize},
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Frontmatter {
|
||||
date: String,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parsing() -> Result<()> {
|
||||
let sample = r#"
|
||||
---toml
|
||||
date = "2023-01-01"
|
||||
---
|
||||
|
||||
# Some Markdown
|
||||
|
||||
With text!"#;
|
||||
|
||||
let (toml, markdown) = toml_frontmatter::parse::<Frontmatter>(sample.trim())?;
|
||||
|
||||
assert_toml_snapshot!("toml", toml);
|
||||
assert_snapshot!("markdown", markdown);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/parsing.rs
|
||||
expression: markdown
|
||||
---
|
||||
# Some Markdown
|
||||
|
||||
With text!
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
source: tests/parsing.rs
|
||||
expression: toml
|
||||
---
|
||||
date = '2023-01-01'
|
Loading…
Reference in New Issue