]> git.r.bdr.sh - rbdr/page/blob - src/file_handler/file_strategies/gemini.rs
04e2b6aae554e9cf2094bb1cbb1b6407096e2def
[rbdr/page] / src / file_handler / file_strategies / gemini.rs
1 pub struct Strategy {}
2
3 use std::path::PathBuf;
4 use std::io::Write;
5 use std::fs::{create_dir_all, read_to_string, File as IOFile};
6
7 use crate::file_handler::{File, FileType, FileHandlerStrategy};
8 use crate::gemini_parser::parse;
9
10 impl Strategy {
11 fn is_title(&self, line: &str) -> bool {
12 line.starts_with("--- title:")
13 }
14
15 fn is_description(&self, line: &str) -> bool {
16 line.starts_with("--- description:")
17 }
18
19 fn get_title<'a>(&self, line: &'a str) -> &'a str {
20 line.split_once("--- title:").unwrap().1
21 }
22
23 fn get_description<'a>(&self, line: &'a str) -> &'a str {
24 line.split_once("--- description:").unwrap().1
25 }
26 }
27
28 impl FileHandlerStrategy for Strategy {
29 fn is(&self, path: &PathBuf) -> bool {
30 if let Some(extension) = path.extension() {
31 return !path.is_dir() && extension == "gmi"
32 }
33 false
34 }
35
36 fn identify(&self) -> FileType {
37 FileType::Gemini
38 }
39
40 fn can_handle(&self, file_type: &FileType) -> bool {
41 match file_type {
42 FileType::Gemini => true,
43 _ => false,
44 }
45 }
46
47 fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File, layout: &String) {
48 let gemini_contents = read_to_string(&file.path).unwrap();
49
50 // Front matter extraction
51 let lines: Vec<&str> = gemini_contents.split("\n").collect();
52 let mut lines_found = 0;
53 let mut title = "";
54 let mut description = "";
55 for line in lines[..2].iter() {
56 if self.is_title(&line) {
57 title = self.get_title(&line).trim();
58 lines_found = lines_found + 1;
59 continue;
60 }
61 if self.is_description(&line) {
62 description = self.get_description(&line).trim();
63 lines_found = lines_found + 1;
64 continue;
65 }
66 }
67
68 let gemini_source = lines[lines_found..].join("\n");
69 let content_html = parse(&gemini_source[..]);
70
71 let generated_html = layout
72 .replace("{{ title }}", title)
73 .replace("{{ description }}", description)
74 .replace("{{ content }}", &content_html[..]);
75
76
77 let relative_path = file.path.strip_prefix(&source).unwrap();
78 let complete_destination = destination.join(relative_path);
79 let destination_parent = complete_destination.parent().unwrap();
80 create_dir_all(destination_parent).unwrap();
81
82 let mut destination_file = IOFile::create(&complete_destination).unwrap();
83 destination_file.write_all(generated_html.as_bytes()).unwrap();
84 }
85 }