use crate::*; use highlight::*; use std::collections::HashMap; pub struct Config { pub config: HashMap, pub last_modified: Option, pub languages: HashMap, pub highlighters: Vec, pub root_redirects: Vec, } impl Config { pub fn new() -> Self { Self { config: HashMap::new(), last_modified: None, languages: HashMap::new(), highlighters: Vec::new(), root_redirects: Vec::new(), } } pub fn get(&self, key: &str) -> String { match self.config.get(key) { Some(value) => value.to_owned(), None => String::new(), } } pub fn parse_file(&mut self, content: &str, last_modified: Option) { if self.last_modified.is_none() || self.last_modified > last_modified { self.last_modified = last_modified; } let mut key = None; let mut value = String::new(); macro_rules! bank_value { () => { value = value.trim().to_string(); if let Some(key) = key { if key == "highlighters" { self.parse_highlighters(&value); } self.config.insert(key, std::mem::take(&mut value)); } }; } for line in content.lines() { if line.starts_with(" ") || line.trim().is_empty() { value.push_str(line.trim()); value.push('\n'); } else { bank_value!(); key = Some(line.trim().to_lowercase().to_string()); } } bank_value!(); } fn parse_highlighters(&mut self, value: &str) { let mut languages = Vec::new(); let mut source = String::new(); macro_rules! bank_sources { () => { if !languages.is_empty() { let i = self.highlighters.len(); for language in std::mem::take(&mut languages) { self.languages.insert(language, i); } let highlighter = Highlighter::from_str(&std::mem::take(&mut source)); self.highlighters.push(highlighter); } }; } for line in value.lines() { if let Some(line) = line.trim().strip_prefix('[') { if let Some(line) = line.strip_suffix(']') { bank_sources!(); languages = line.split('/').map(|s| s.trim().to_string()).collect(); continue; } } source.push_str(line); source.push('\n'); } bank_sources!(); } }