webmark/
lib.rs

1use std::path::Path;
2use std::path::PathBuf;
3
4pub type WebError = Box<dyn std::error::Error>;
5
6pub fn get_destiny(from_url: &str, to_root: impl AsRef<Path>) -> PathBuf {
7    let start = from_url.find("://").unwrap();
8    let url = &from_url[start+3..];
9    let mut result = to_root.as_ref().to_owned();
10    for part in url.split("/") {
11        let part = part
12            .replace("<", "_")
13            .replace(">", "_")
14            .replace(":", "_")
15            .replace("\"", "_")
16            .replace("\\", "_")
17            .replace("|", "_")
18            .replace("?", "_")
19            .replace("*", "_");
20        result = result.join(part);
21    }
22    result
23}
24
25pub async fn make(from_url: &str, to_root: impl AsRef<Path>) -> Result<(), WebError> {
26    let destiny = get_destiny(from_url, to_root);
27    std::fs::create_dir_all(&destiny)?;
28    let res = reqwest::get(from_url).await?;
29    let doc = res.text().await?;
30    let mut result = String::new();
31    let mut on_bracket = false;
32    let mut on_bracket_from: usize = 0;
33    let mut on_bracket_opened_single_quote = false;
34    let mut on_bracket_opened_double_quote = false;
35    let mut on_bracket_tree: Vec<&str> = Vec::new();
36    let mut on_content_from: usize = 0;
37    for indexed_char in doc.char_indices() {
38        let index = indexed_char.0;
39        let actual = indexed_char.1;
40        if on_bracket {
41            if on_bracket_opened_single_quote {
42                if actual == '\'' {
43                    on_bracket_opened_single_quote = false;
44                }
45            } else if on_bracket_opened_double_quote {
46                if actual == '"' {
47                    on_bracket_opened_double_quote = false;
48                }
49            } else {
50                if actual == '\'' {
51                    on_bracket_opened_single_quote = true;
52                } else if actual == '"' {
53                    on_bracket_opened_double_quote = true;
54                } else if actual == '>' {
55                    on_bracket = false;
56                    on_content_from = index + 1;
57                    let bracket = &doc[on_bracket_from..on_content_from];
58                    on_bracket_tree.push(bracket);
59                    proc_bracket(bracket, &on_bracket_tree, &mut result);
60                }
61            }
62        } else {
63            if actual == '<' {
64                if index > on_content_from {
65                    let content = &doc[on_content_from..index];
66                    proc_content(content, &mut result);
67                }
68                on_bracket = true;
69                on_bracket_from = index;
70                on_bracket_opened_single_quote = false;
71                on_bracket_opened_double_quote = false;
72            }
73        }
74    }
75    std::fs::write(&destiny.join("contents.md"), result)?;
76    Ok(())
77}
78
79fn proc_bracket(bracket: &str, _tree: &Vec<&str>, result: &mut String) {
80    result.push_str("x----------------------------------------------------x\n");
81    result.push_str("Bracket: ");
82    result.push_str(bracket);
83    result.push_str("\n");
84}
85
86fn proc_content(content: &str, result: &mut String) {
87    result.push_str("x----------------------------------------------------x\n");
88    result.push_str("Content: ");
89    result.push_str(content);
90    result.push_str("\n");
91}
92
93
94