void-werefox-cafe/void-fe/src/utils/helpers.rs

158 lines
5.4 KiB
Rust

use markdown::Options;
use rand::seq::SliceRandom;
use rust_embed::RustEmbed;
use std::collections::{HashMap, VecDeque};
use super::prop_structs::{PoemDatabase, PoemStruct};
#[derive(RustEmbed)]
#[folder = "data/other"]
struct OtherData;
#[derive(RustEmbed)]
#[folder = "data/poems"]
pub struct Poems;
impl PoemDatabase {
pub fn new() -> PoemDatabase {
PoemDatabase {
poem_list: Vec::<(String, String)>::new(),
poem_hashmap: HashMap::<String, PoemStruct>::new(),
}
}
// There's no need to actually make a database yet, but maybe in the future...
pub async fn build_poem_database(&mut self) {
for p in Poems::iter() {
let filename = p.to_string();
let poem_content = Poems::get(&filename).expect("Found poem {filename:?}");
let mut poem_to_str = std::str::from_utf8(poem_content.data.as_ref())
.expect("Poem is valid UT8.")
.lines();
let poem_title = poem_to_str.next().expect("No title specified.");
let poem_content = poem_to_str.into_iter().collect::<Vec<&str>>().join("\n");
let poem_title_to_html_string =
markdown::to_html_with_options(poem_title, &Options::gfm()).unwrap();
let poem_content_to_html_string =
markdown::to_html_with_options(poem_content.as_str(), &Options::gfm()).unwrap();
let mut split_filename = filename.trim_end_matches(".md").split("_");
let creation_date = split_filename.next().expect("Obtained creation date");
let slug = split_filename.next().expect("Obtained slug");
self.poem_list
.push((creation_date.to_string(), slug.to_string()));
let poem_struct = PoemStruct {
title: poem_title_to_html_string.to_string(),
content: poem_content_to_html_string,
creation_date: creation_date.to_string(),
};
self.poem_hashmap.insert(slug.to_string(), poem_struct);
}
self.poem_list.sort_by_key(|k| k.0.clone())
}
pub fn get_poem(&self, slug: String) -> PoemStruct {
self.poem_hashmap
.get(slug.as_str())
.expect("Grabbed poem from database")
.clone()
}
pub fn get_poem_list(&self) -> Vec<(String, String)> {
self.poem_list
.iter()
.map(|s| {
(
s.1.clone(),
self.poem_hashmap
.get(&s.1)
.expect("Got poemstruct from database")
.title
.clone(),
)
})
.collect::<Vec<(String, String)>>()
.clone()
}
pub fn get_oldest_entry(&self, current: String) -> String {
let mut poem_list = VecDeque::from_iter(self.poem_list.iter());
let oldest = poem_list
.pop_front()
.expect("There is an entry in this list of poems.")
.1
.clone();
if current == oldest {
return format!("/poems/{current}#");
}
format!("/poems/{oldest}")
}
pub fn get_latest_entry(&self, current: String) -> String {
let mut poem_list = self.poem_list.clone();
let latest = poem_list
.pop()
.expect("There is an entry in this list of poems.")
.1
.clone();
if current == latest {
return format!("/poems/{current}#");
}
format!("/poems/{latest}")
}
pub fn get_previous_entry(&self, current: String) -> String {
let poem_list = self.poem_list.clone();
match poem_list.iter().enumerate().find_map(|(index, p)| {
if p.1 == current {
if index != 0 {
Some(poem_list[index - 1].1.clone())
} else {
None
}
} else {
None
}
}) {
Some(entry) => format!("/poems/{entry}"),
None => format!("/poems/{current}"),
}
}
pub fn get_next_entry(&self, current: String) -> String {
let poem_list = self.poem_list.clone();
match poem_list.iter().enumerate().find_map(|(index, p)| {
if p.1 == current {
if index != poem_list.len() - 1 {
Some(poem_list[index + 1].1.clone())
} else {
None
}
} else {
None
}
}) {
Some(entry) => format!("/poems/{entry}"),
None => format!("/poems/{current}"),
}
}
pub fn get_random_entry(&self) -> String {
let poem_list = self.poem_list.clone();
let mut rng = rand::thread_rng();
let random_entry = poem_list
.choose(&mut rng)
.expect("Got a valid entry")
.1
.clone();
format!("/poems/{random_entry}")
}
}
pub fn get_homepage_paragraph() -> String {
let homepage_paragraph_content =
OtherData::get("homepage.md").expect("Found homepage paragraph.");
let homepage_paragraph_to_string =
std::str::from_utf8(homepage_paragraph_content.data.as_ref())
.expect("Homepage file is valid UTF-8");
let test =
markdown::to_html_with_options(homepage_paragraph_to_string, &Options::gfm()).unwrap();
test
}