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.52 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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();
    
    
    peterrabbit's avatar
    peterrabbit committed
            obj.root_page.build_body_template(
                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() {
    
    peterrabbit's avatar
    peterrabbit committed
                p.build_body_template(
                    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());
            let root_page = root_page.unwrap();
            assert_eq!(format!("{}", root_page.body), "<h1>testing</h1>");
    
    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());
            let sub_page = sub_page.unwrap();
            assert_eq!(format!("{}", sub_page.body), "<h1>testing subpage</h1>");
    
    peterrabbit's avatar
    peterrabbit committed
            let nested_page = website.get_page_by_url(&PathBuf::from("subpage/nested"));
            assert!(nested_page.is_some());
            let nested_page = nested_page.unwrap();
            assert_eq!(format!("{}", nested_page.body), "<h1>testing nested</h1>");
        }
    }