diff options
Diffstat (limited to 'src/guilds.rs')
-rw-r--r-- | src/guilds.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/guilds.rs b/src/guilds.rs new file mode 100644 index 0000000..0eff6ad --- /dev/null +++ b/src/guilds.rs @@ -0,0 +1,79 @@ +//! Guild name retrieval and caching functions. +use std::collections::HashMap; +use std::fs::File; +use std::path::PathBuf; +use std::sync::RwLock; + +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +static CACHE: Lazy<RwLock<HashMap<String, Guild>>> = Lazy::new(|| RwLock::new(HashMap::new())); + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Guild { + tag: String, + name: String, +} + +impl Guild { + pub fn tag(&self) -> &str { + &self.tag + } + + pub fn name(&self) -> &str { + &self.name + } +} + +/// Looks up the given guild. +/// +/// This checks the cache first, and if nothing was found, it will hit the API. +pub fn lookup(api_id: &str) -> Option<Guild> { + { + let cache = CACHE.read().unwrap(); + if let Some(guild) = cache.get(api_id) { + return Some(guild.clone()); + } + } + + let mut cache = CACHE.write().unwrap(); + let url = format!("https://api.guildwars2.com/v2/guild/{}", api_id); + let result = ureq::get(&url) + .call() + .into_json() + .expect("Invalid JSON in API response"); + let name = result["name"].as_str()?; + let tag = result["tag"].as_str()?; + let guild = Guild { + tag: tag.into(), + name: name.into(), + }; + cache.insert(api_id.into(), guild.clone()); + Some(guild) +} + +fn cache_path() -> PathBuf { + let mut cache_path = dirs::cache_dir().unwrap(); + cache_path.push("raidgrep"); + cache_path +} + +/// Loads the cache from the file system. +pub fn prepare_cache() { + let path = cache_path(); + if !path.is_file() { + return; + } + + let file = File::open(path).expect("Unable to read cache file"); + let cache = serde_json::from_reader(file).expect("Cache file has invalid format"); + let mut target = CACHE.write().unwrap(); + *target = cache; +} + +/// Saves the cache to the file system +pub fn save_cache() { + let path = cache_path(); + let file = File::create(path).expect("Cannot open cache for writing"); + serde_json::to_writer(file, &*CACHE.read().unwrap()).unwrap(); +} |