This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1use std::{ 2 collections::HashMap, 3 fs::File, 4 io::{BufRead, BufReader}, 5 path::PathBuf, 6}; 7 8use serde::Deserialize; 9use strum::IntoEnumIterator; 10use strum_macros::EnumIter; 11#[cfg(feature = "web")] 12use wasm_bindgen::prelude::*; 13 14#[cfg_attr(feature = "web", wasm_bindgen)] 15#[derive(Debug, Clone, Copy, PartialEq, EnumIter)] 16pub enum Color { 17 Black, 18 White, 19 Red, 20 Green, 21 Blue, 22 Yellow, 23 Orange, 24 Purple, 25 Brown, 26 Cyan, 27 Pink, 28 Gray, 29} 30 31impl Color { 32 pub fn all() -> Vec<Color> { 33 Color::iter().collect() 34 } 35} 36 37impl Default for Color { 38 fn default() -> Self { 39 Self::Black 40 } 41} 42 43impl From<&str> for Color { 44 fn from(s: &str) -> Self { 45 match s { 46 "black" => Color::Black, 47 "white" => Color::White, 48 "red" => Color::Red, 49 "green" => Color::Green, 50 "blue" => Color::Blue, 51 "yellow" => Color::Yellow, 52 "orange" => Color::Orange, 53 "purple" => Color::Purple, 54 "brown" => Color::Brown, 55 "cyan" => Color::Cyan, 56 "pink" => Color::Pink, 57 "gray" => Color::Gray, 58 _ => panic!("Invalid color: {}", s), 59 } 60 } 61} 62 63impl Color { 64 pub fn render(self, mapping: &ColorMapping) -> String { 65 match self { 66 Color::Black => mapping.black.to_string(), 67 Color::White => mapping.white.to_string(), 68 Color::Red => mapping.red.to_string(), 69 Color::Green => mapping.green.to_string(), 70 Color::Blue => mapping.blue.to_string(), 71 Color::Yellow => mapping.yellow.to_string(), 72 Color::Orange => mapping.orange.to_string(), 73 Color::Purple => mapping.purple.to_string(), 74 Color::Brown => mapping.brown.to_string(), 75 Color::Cyan => mapping.cyan.to_string(), 76 Color::Pink => mapping.pink.to_string(), 77 Color::Gray => mapping.gray.to_string(), 78 } 79 } 80 81 pub fn name(&self) -> String { 82 match self { 83 Color::Black => "black", 84 Color::White => "white", 85 Color::Red => "red", 86 Color::Green => "green", 87 Color::Blue => "blue", 88 Color::Yellow => "yellow", 89 Color::Orange => "orange", 90 Color::Purple => "purple", 91 Color::Brown => "brown", 92 Color::Cyan => "cyan", 93 Color::Pink => "pink", 94 Color::Gray => "gray", 95 } 96 .to_string() 97 } 98} 99 100#[cfg_attr(feature = "web", wasm_bindgen(getter_with_clone))] 101#[derive(Debug, Deserialize, Clone)] 102pub struct ColorMapping { 103 pub black: String, 104 pub white: String, 105 pub red: String, 106 pub green: String, 107 pub blue: String, 108 pub yellow: String, 109 pub orange: String, 110 pub purple: String, 111 pub brown: String, 112 pub cyan: String, 113 pub pink: String, 114 pub gray: String, 115} 116 117#[cfg_attr(feature = "web", wasm_bindgen)] 118impl ColorMapping { 119 // wasm_bindegen is not supported on trait impls 120 #[allow(clippy::should_implement_trait)] 121 pub fn default() -> Self { 122 ColorMapping { 123 black: "black".to_string(), 124 white: "white".to_string(), 125 red: "red".to_string(), 126 green: "green".to_string(), 127 blue: "blue".to_string(), 128 yellow: "yellow".to_string(), 129 orange: "orange".to_string(), 130 purple: "purple".to_string(), 131 brown: "brown".to_string(), 132 pink: "pink".to_string(), 133 gray: "gray".to_string(), 134 cyan: "cyan".to_string(), 135 } 136 } 137 138 pub fn from_json(content: &str) -> ColorMapping { 139 let json: HashMap<String, String> = 140 serde_json::from_str(content).unwrap(); 141 ColorMapping::from_hashmap(json) 142 } 143 144 pub fn from_css(content: &str) -> ColorMapping { 145 let mut mapping = ColorMapping::default(); 146 for line in content.lines() { 147 mapping.from_css_line(line); 148 } 149 mapping 150 } 151} 152 153#[cfg(not(feature = "web"))] 154impl Default for ColorMapping { 155 fn default() -> Self { 156 ColorMapping::default() 157 } 158} 159 160impl ColorMapping { 161 pub fn from_cli_args(args: &Vec<String>) -> ColorMapping { 162 let mut colormap: HashMap<String, String> = HashMap::new(); 163 for mapping in args { 164 if !mapping.contains(':') { 165 println!("Invalid color mapping: {}", mapping); 166 std::process::exit(1); 167 } 168 let mut split = mapping.split(':'); 169 let color = split.next().unwrap(); 170 let hex = split.next().unwrap(); 171 colormap.insert(color.to_string(), hex.to_string()); 172 } 173 ColorMapping::from_hashmap(colormap) 174 } 175 176 pub fn from_hashmap(hashmap: HashMap<String, String>) -> ColorMapping { 177 ColorMapping { 178 black: hashmap 179 .get("black") 180 .unwrap_or(&ColorMapping::default().black) 181 .to_string(), 182 white: hashmap 183 .get("white") 184 .unwrap_or(&ColorMapping::default().white) 185 .to_string(), 186 red: hashmap 187 .get("red") 188 .unwrap_or(&ColorMapping::default().red) 189 .to_string(), 190 green: hashmap 191 .get("green") 192 .unwrap_or(&ColorMapping::default().green) 193 .to_string(), 194 blue: hashmap 195 .get("blue") 196 .unwrap_or(&ColorMapping::default().blue) 197 .to_string(), 198 yellow: hashmap 199 .get("yellow") 200 .unwrap_or(&ColorMapping::default().yellow) 201 .to_string(), 202 orange: hashmap 203 .get("orange") 204 .unwrap_or(&ColorMapping::default().orange) 205 .to_string(), 206 purple: hashmap 207 .get("purple") 208 .unwrap_or(&ColorMapping::default().purple) 209 .to_string(), 210 brown: hashmap 211 .get("brown") 212 .unwrap_or(&ColorMapping::default().brown) 213 .to_string(), 214 cyan: hashmap 215 .get("cyan") 216 .unwrap_or(&ColorMapping::default().cyan) 217 .to_string(), 218 pink: hashmap 219 .get("pink") 220 .unwrap_or(&ColorMapping::default().pink) 221 .to_string(), 222 gray: hashmap 223 .get("gray") 224 .unwrap_or(&ColorMapping::default().gray) 225 .to_string(), 226 } 227 } 228 229 pub fn from_file(path: PathBuf) -> ColorMapping { 230 match path.extension().map(|e| e.to_str().unwrap()) { 231 Some("css") => ColorMapping::from_css_file(path), 232 Some("json") => ColorMapping::from_json_file(path), 233 ext => panic!( 234 "Invalid colormap file format. Must be css or json, is {:?}.", 235 ext 236 ), 237 } 238 } 239 240 pub fn from_json_file(path: PathBuf) -> ColorMapping { 241 let file = File::open(path).unwrap(); 242 let reader = BufReader::new(file); 243 let json: HashMap<String, String> = 244 serde_json::from_reader(reader).unwrap(); 245 ColorMapping::from_hashmap(json) 246 } 247 248 pub fn from_css_file(path: PathBuf) -> ColorMapping { 249 let mut mapping = ColorMapping::default(); 250 let file = File::open(path).unwrap(); 251 let lines = std::io::BufReader::new(file).lines(); 252 for line in lines.map_while(Result::ok) { 253 mapping.from_css_line(&line); 254 } 255 mapping 256 } 257 258 #[allow(clippy::wrong_self_convention)] 259 fn from_css_line(&mut self, line: &str) { 260 if let Some((name, value)) = line.trim().split_once(':') { 261 let value = value.trim().trim_end_matches(';').to_owned(); 262 match name.trim() { 263 "black" => self.black = value, 264 "white" => self.white = value, 265 "red" => self.red = value, 266 "green" => self.green = value, 267 "blue" => self.blue = value, 268 "yellow" => self.yellow = value, 269 "orange" => self.orange = value, 270 "purple" => self.purple = value, 271 "brown" => self.brown = value, 272 "cyan" => self.cyan = value, 273 "pink" => self.pink = value, 274 "gray" => self.gray = value, 275 _ => (), 276 } 277 } 278 } 279}