use paige::{Amanda, Frontmatter}; use wikarden::{WikError, Wikarden}; use crate::handler::quark::PageFrontmatter; pub struct Source<'p> { full_content: &'p str, frontmatter: PageFrontmatter<'p>, content: &'p str, } impl<'p> Source<'p> { pub async fn from_wik(wik: &Wikarden, path: &str) -> Result { let source = wik.source(path).await?; //SAFETY: This reference must live for the lifetime of this struct let source_text: &'p str = Box::leak(source.data.into_boxed_str()); let maybe_paige = Self::parse_frontmatter(source_text); let mut pf = PageFrontmatter::default(); let mut content = source_text; if let Some(paige) = maybe_paige { let frontmatter_ptr = (&paige.frontmatter) as *const Frontmatter; let frontmatter: &'p Frontmatter = unsafe { frontmatter_ptr.as_ref_unchecked() }; pf.from_frontmatter(frontmatter); content = paige.content; } Ok(Self { full_content: source_text, frontmatter: pf, content, }) } fn parse_frontmatter(raw: &'p str) -> Option> { match paige::Templated::parse(raw) { Ok(tpl) => Some(tpl), Err(_) => None, } } pub fn frontmatter(&self) -> &PageFrontmatter<'p> { &self.frontmatter } pub fn content(&self) -> &str { self.content } pub fn amanda(&self) -> Amanda<'p> { Amanda::parse(self.content) } } impl<'p> Drop for Source<'p> { fn drop(&mut self) { // Doing shenenegains because I cannot have a &mut str in the struct let mut_ptr = self.full_content.as_ptr(); drop(unsafe { Box::from_raw(mut_ptr as *mut u8) }); } }