1
Fork 0

Add source and test files.

This commit is contained in:
Bauke 2023-01-06 14:03:43 +01:00
parent 5b6c33bccd
commit 69778bbfa6
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
5 changed files with 132 additions and 0 deletions

71
source/lib.rs Normal file
View File

@ -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()))
}

20
tests/errors.rs Normal file
View File

@ -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();
}

29
tests/parsing.rs Normal file
View File

@ -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(())
}

View File

@ -0,0 +1,7 @@
---
source: tests/parsing.rs
expression: markdown
---
# Some Markdown
With text!

View File

@ -0,0 +1,5 @@
---
source: tests/parsing.rs
expression: toml
---
date = '2023-01-01'