Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
website.rs 3.37 KiB
Newer Older
peterrabbit's avatar
peterrabbit committed
use crate::app::AppConfig;
peterrabbit's avatar
peterrabbit committed
use crate::website::page::{Page, PageTemplate};
peterrabbit's avatar
peterrabbit committed
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
peterrabbit's avatar
peterrabbit committed
use std::path::PathBuf;
peterrabbit's avatar
peterrabbit committed

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WebSite {
peterrabbit's avatar
peterrabbit committed
    root_page: Page,
peterrabbit's avatar
peterrabbit committed
    #[serde(default = "AssetsIndex::new")]
peterrabbit's avatar
peterrabbit committed
    assets_index: AssetsIndex,
peterrabbit's avatar
peterrabbit committed
    templates: Vec<PageTemplate>,
peterrabbit's avatar
peterrabbit committed
    #[serde(default = "HashMap::new")]
peterrabbit's avatar
peterrabbit committed
    pages_index: HashMap<PathBuf, Page>,
peterrabbit's avatar
peterrabbit committed
}

peterrabbit's avatar
peterrabbit committed
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AssetsIndex {
    pub images: Vec<String>,
    pub sounds: Vec<String>,
    pub videos: Vec<String>,
    pub docs: Vec<String>,
    pub source_code: Vec<String>,
}

peterrabbit's avatar
peterrabbit committed
impl AssetsIndex {
    pub fn new() -> Self {
        AssetsIndex {
            images: Vec::new(),
            sounds: Vec::new(),
            videos: Vec::new(),
            docs: Vec::new(),
            source_code: Vec::new(),
        }
    }
}

peterrabbit's avatar
peterrabbit committed
impl WebSite {
peterrabbit's avatar
peterrabbit committed
    pub fn from_json(json: &str) -> Self {
peterrabbit's avatar
peterrabbit committed
        let mut obj: WebSite = serde_json::from_str(json).unwrap();

Pierre Jarriges's avatar
Pierre Jarriges committed
        obj.root_page.build_with_template(
peterrabbit's avatar
peterrabbit committed
            obj.templates
                .iter()
                .find(|t| t.name == obj.root_page.template_name)
                .expect("Page template not found")
                .clone(),
peterrabbit's avatar
peterrabbit committed
        );
peterrabbit's avatar
peterrabbit committed

        obj.root_page.build_html();

peterrabbit's avatar
peterrabbit committed
        for p in obj.root_page.sub_pages.iter_mut() {
Pierre Jarriges's avatar
Pierre Jarriges committed
            p.build_with_template(
peterrabbit's avatar
peterrabbit committed
                obj.templates
                    .iter()
                    .find(|t| t.name == p.template_name)
                    .expect("Page template not found")
                    .clone(),
peterrabbit's avatar
peterrabbit committed
            );
peterrabbit's avatar
peterrabbit committed
            p.build_html();
peterrabbit's avatar
peterrabbit committed
        }
peterrabbit's avatar
peterrabbit committed

        obj.build_assets_index();
        obj.build_pages_index(obj.root_page.clone(), PathBuf::from("/"));

peterrabbit's avatar
peterrabbit committed
        obj
peterrabbit's avatar
peterrabbit committed
    pub fn load(config: &AppConfig) -> WebSite {
        let file_path = match &config.load {
            None => std::env::current_dir()
                .unwrap()
                .join("templates")
                .join("new_website.json"),
            Some(pth) => pth.clone(),
        };

peterrabbit's avatar
peterrabbit committed
        WebSite::from_json(&std::fs::read_to_string(file_path).unwrap())
peterrabbit's avatar
peterrabbit committed
    }

peterrabbit's avatar
peterrabbit committed
    fn build_pages_index(&mut self, root_page: Page, from_url: PathBuf) {
        let url = from_url.join(&root_page.metadata.url_slug);
peterrabbit's avatar
peterrabbit committed

peterrabbit's avatar
peterrabbit committed
        self.pages_index.insert(url.clone(), root_page.clone());
peterrabbit's avatar
peterrabbit committed

peterrabbit's avatar
peterrabbit committed
        for p in root_page.sub_pages {
            self.build_pages_index(p, url.clone());
peterrabbit's avatar
peterrabbit committed
    fn build_assets_index(&mut self) {
peterrabbit's avatar
peterrabbit committed
        return;
peterrabbit's avatar
peterrabbit committed
    }

    pub fn get_page_by_url(&self, url: &PathBuf) -> Option<&Page> {
        self.pages_index.get(&PathBuf::from("/").join(url))
peterrabbit's avatar
peterrabbit committed
#[cfg(test)]
mod test_website {
    use super::*;
    use crate::testing::TEST_JSON_WEBSITE;
peterrabbit's avatar
peterrabbit committed

peterrabbit's avatar
peterrabbit committed
    #[test]
    fn test_index_pages_by_slug() {
        let website = WebSite::from_json(TEST_JSON_WEBSITE);
        let root_page = website.get_page_by_url(&PathBuf::from("/"));
        assert!(root_page.is_some());
Pierre Jarriges's avatar
Pierre Jarriges committed
        assert_eq!(root_page.unwrap().metadata.title, "TEST");
peterrabbit's avatar
peterrabbit committed

peterrabbit's avatar
peterrabbit committed
        let sub_page = website.get_page_by_url(&PathBuf::from("subpage"));
        assert!(sub_page.is_some());
Pierre Jarriges's avatar
Pierre Jarriges committed
        assert_eq!(sub_page.unwrap().metadata.title, "TEST SUBPAGE");
peterrabbit's avatar
peterrabbit committed
        let nested_page = website.get_page_by_url(&PathBuf::from("subpage/nested"));
        assert!(nested_page.is_some());
Pierre Jarriges's avatar
Pierre Jarriges committed
        assert_eq!(nested_page.unwrap().metadata.title, "TEST NESTED");