onelo_backend/files/
mod.rs1use crate::context::Result;
2use regex::Regex;
3use std::error::Error;
4use std::fmt;
5use std::fs;
6use std::path::{Path, PathBuf};
7
8#[derive(Debug)]
9struct SplitError(String);
10
11impl fmt::Display for SplitError {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 write!(f, "{}", self.0)
14 }
15}
16
17impl Error for SplitError {}
18
19pub fn get_markdown_files<P: AsRef<Path>>(path: P) -> Result<Vec<PathBuf>> {
21 let mut paths = vec![];
22
23 for result in fs::read_dir(path)? {
24 let path = result?.path();
25
26 if is_valid_file(&path) {
27 paths.push(path);
28 }
29 }
30
31 Ok(paths)
32}
33
34fn is_valid_file(path: &PathBuf) -> bool {
36 if let Some(ext) = path.extension() {
37 return ext == "md";
38 }
39
40 false
41}
42
43pub fn get_file_content<P: AsRef<Path>>(path: P) -> Result<String> {
45 let file = fs::read_to_string(path)?;
46
47 Ok(file)
48}
49
50pub fn split_content<'c>(content: &'c str) -> Result<(&'c str, &'c str)> {
52 let split_regex =
53 Regex::new(r"^[[:space:]]*\+\+\+(\r?\n(?s).*?(?-s))\+\+\+\r?\n?((?s).*(?-s))$")
54 .expect("Something went wrong when compiling a regular expression.");
55
56 if !split_regex.is_match(content) {
57 return Err(Box::new(SplitError(
58 "Couldn't find metadata. Did you forget to add `+++`?".into(),
59 )));
60 }
61
62 let splitted_content = split_regex.captures(content).ok_or(SplitError(
63 "Something went wrong when splitting the content.".into(),
64 ))?;
65
66 Ok((
67 splitted_content
68 .get(1)
69 .ok_or(SplitError("Couldn't find any metadata".into()))?
70 .as_str()
71 .trim(),
72 splitted_content
73 .get(2)
74 .ok_or(SplitError("Couldn't find any content".into()))?
75 .as_str()
76 .trim(),
77 ))
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_get_only_md_files() {
86 let paths = get_markdown_files("test/files");
87 assert_eq!(paths.unwrap().len(), 2);
88 }
89
90 #[test]
91 fn test_get_markdown_file_content() {
92 let file_content = get_file_content("test/files/01.md");
93 let file_content_string = file_content.unwrap();
94
95 let expected = r#"+++
96[metadata]
97id = "01fbd72a-5ad4-4d4d-bc6e-7973e65e02b6"
98+++
99
100# Lorem ipsum
101
102Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc posuere nibh eget tortor rhoncus dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit."#;
103
104 assert_eq!(file_content_string, expected.to_string());
105 }
106
107 #[test]
108 fn test_split_content_with_metadata() {
109 let content = r#"+++
110[metadata]
111id = "01fbd72a-5ad4-4d4d-bc6e-7973e65e02b6"
112+++
113
114# Lorem ipsum
115
116Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc posuere nibh eget tortor rhoncus dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit."#;
117 let splitted_content = split_content(content).unwrap();
118
119 assert_eq!(
120 "[metadata]\nid = \"01fbd72a-5ad4-4d4d-bc6e-7973e65e02b6\"",
121 splitted_content.0
122 );
123
124 assert_eq!(
125 "# Lorem ipsum\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc posuere nibh eget tortor rhoncus dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
126 splitted_content.1
127 );
128 }
129
130 #[test]
131 fn test_split_content_with_empty_metadata() {
132 let content = r#"+++
133+++
134
135# Lorem ipsum
136
137Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc posuere nibh eget tortor rhoncus dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit."#;
138 assert_eq!(split_content(content).is_ok(), true);
139 }
140
141 #[test]
142 fn test_split_content_without_metadata() {
143 let content = r#"
144# Lorem ipsum
145
146Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc posuere nibh eget tortor rhoncus dictum. Lorem ipsum dolor sit amet, consectetur adipiscing elit."#;
147
148 assert_eq!(split_content(content).is_err(), true);
149 }
150}