1use crate::errors::AtomicResult;
6use std::collections::hash_map::IntoIter;
7use std::{collections::HashMap, fs, path::Path};
8#[derive(Clone)]
10pub struct Mapping {
11 hashmap: HashMap<String, String>,
12}
13
14impl Mapping {
15 pub fn init() -> Mapping {
16 let hashmap: HashMap<String, String> = HashMap::new();
17
18 Mapping { hashmap }
19 }
20
21 pub fn try_mapping_or_url(&self, mapping_or_url: &str) -> Option<String> {
25 match self.get(mapping_or_url) {
26 Some(hit) => Some(hit.into()),
27 None => {
28 if is_url(mapping_or_url) {
30 return Some(mapping_or_url.into());
31 }
32 None
33 }
34 }
35 }
36
37 pub fn insert(&mut self, shortname: String, url: String) {
39 self.hashmap.insert(shortname, url);
40 }
41
42 pub fn get(&self, bookmark: &str) -> Option<&String> {
44 self.hashmap.get(bookmark)
45 }
46
47 pub fn read_mapping_from_file(&mut self, path: &Path) -> AtomicResult<()> {
49 let mapping_string = std::fs::read_to_string(path)?;
50 self.parse_mapping(&mapping_string)?;
51 Ok(())
52 }
53
54 pub fn parse_mapping(&mut self, mapping_string: &str) -> AtomicResult<()> {
60 for line in mapping_string.lines() {
61 match line.chars().next() {
62 Some('#') => {}
63 Some(' ') => {}
64 Some(_) => {
65 let split: Vec<&str> = line.split('=').collect();
66 if split.len() == 2 {
67 self.hashmap
68 .insert(String::from(split[0]), String::from(split[1]));
69 } else {
70 return Err(format!("Error reading line {:?}", line).into());
71 };
72 }
73 None => {}
74 };
75 }
76 Ok(())
77 }
78
79 pub fn contains_key(&self, key: &str) -> bool {
81 self.hashmap.contains_key(key)
82 }
83
84 pub fn write_mapping_to_disk(&self, path: &Path) {
86 let mut file_string: String = String::new();
87 for (key, url) in self.hashmap.clone().iter() {
88 let map = format!("{}={}\n", key, url);
89 file_string.push_str(&map);
90 }
91 fs::create_dir_all(path.parent().expect("Cannot create above root"))
92 .expect("Unable to create dirs");
93 fs::write(path, file_string).expect("Unable to write file");
94 }
95
96 pub fn populate(&mut self) -> AtomicResult<()> {
97 let mapping = include_str!("../defaults/default_mapping.amp");
98 self.parse_mapping(mapping)?;
99 Ok(())
100 }
101}
102
103pub fn is_url(string: &str) -> bool {
105 string.starts_with("http") || string.starts_with("_:")
107}
108
109impl IntoIterator for Mapping {
110 type Item = (String, String);
111 type IntoIter = IntoIter<String, String>;
112
113 fn into_iter(self) -> Self::IntoIter {
114 self.hashmap.into_iter()
115 }
116}