aboutsummaryrefslogtreecommitdiff
path: root/src/guilds.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/guilds.rs')
-rw-r--r--src/guilds.rs79
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();
+}