equt_md_ext/
parser.rs

1use crate::{MarkdownExt, Share};
2use equt_md as markdown;
3use equt_md_error::Result;
4use equt_md_frontmatter::FrontMatter;
5use serde_yaml;
6use std::iter::Peekable;
7use std::rc::Rc;
8use std::cell::RefCell;
9
10/// A wrapper for the original [`Parser`].
11///
12/// [`Parser`]: https://docs.rs/equt-md/*/equt_md/struct.Parser.html
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14pub struct Parser<'e> {
15    parser: Peekable<markdown::Parser<'e>>,
16    frontmatter: Share<RefCell<Option<FrontMatter>>>,
17}
18
19impl<'e> Parser<'e> {
20    /// Create a **full-feature** parser.
21    pub fn new(text: &'e str) -> Result<Parser<'e>> {
22        let mut parser = markdown::Parser::new_ext(text, markdown::Options::all()).peekable();
23        return if let Some(markdown::Event::Frontmatter(s)) = parser.peek() {
24            let fm: FrontMatter = serde_yaml::from_str(s)?;
25            parser.next();
26            Ok(Parser {
27                parser,
28                frontmatter: Rc::new(RefCell::new(Some(fm))).into(),
29            })
30        } else {
31            Ok(Parser {
32                parser,
33                frontmatter: Rc::new(RefCell::new(None)).into(),
34            })
35        };
36    }
37}
38
39impl<'e> Iterator for Parser<'e> {
40    type Item = markdown::Event<'e>;
41
42    fn next(&mut self) -> Option<Self::Item> {
43        self.parser.next()
44    }
45}
46
47impl<'e> MarkdownExt<markdown::Event<'e>> for Parser<'e> {
48    fn frontmatter(&mut self) -> &mut Share<RefCell<Option<FrontMatter>>> {
49        &mut self.frontmatter
50    }
51}