about summary refs log tree commit diff
path: root/splorm/src/handler/quark/markup/source.rs
blob: 41529fc0a8186a226d4937de49f439f397293d5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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<Self, WikError> {
		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<paige::Templated<'p>> {
		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) });
	}
}