summaryrefslogtreecommitdiffstats
path: root/src/stackexchange/local_storage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stackexchange/local_storage.rs')
-rw-r--r--src/stackexchange/local_storage.rs57
1 files changed, 54 insertions, 3 deletions
diff --git a/src/stackexchange/local_storage.rs b/src/stackexchange/local_storage.rs
index 5874611..1d0af2c 100644
--- a/src/stackexchange/local_storage.rs
+++ b/src/stackexchange/local_storage.rs
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::fs;
+use std::ops::Deref;
use std::path::Path;
use crate::config::Config;
@@ -7,6 +8,7 @@ use crate::error::{Error, Result};
use crate::utils;
use super::api::{Api, Site};
+use super::Question;
/// This structure allows interacting with locally cached StackExchange metadata.
pub struct LocalStorage {
@@ -62,8 +64,9 @@ impl LocalStorage {
site_codes.iter().find(|s| !hm.contains_key(&s.as_str()))
}
- pub fn get_urls(&self, site_codes: &[String]) -> HashMap<String, String> {
- self.sites
+ pub fn get_site_map(&self, site_codes: &[String]) -> SiteMap {
+ let inner = self
+ .sites
.iter()
.filter_map(move |site| {
let _ = site_codes
@@ -71,6 +74,54 @@ impl LocalStorage {
.find(|&sc| *sc == site.api_site_parameter)?;
Some((site.api_site_parameter.to_owned(), site.site_url.to_owned()))
})
- .collect()
+ .collect();
+ SiteMap { inner }
+ }
+}
+
+/// Just a map of site codes to site URLs, shareable across the app. These are
+/// only the sites relevant to the configuration / query, not all cached SE
+/// sites.
+#[derive(Debug)]
+pub struct SiteMap {
+ inner: HashMap<String, String>,
+}
+
+impl Deref for SiteMap {
+ type Target = HashMap<String, String>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
+}
+
+impl SiteMap {
+ /// Get SE answer url. Panics if site was not set on the question, or
+ /// site code not found in the map.
+ pub fn answer_url<S>(&self, question: &Question<S>, answer_id: u32) -> String {
+ // answer link actually doesn't need question id
+ let site_url = self.site_url(question);
+ format!("https://{site_url}/a/{answer_id}")
+ }
+
+ /// Get SE question url. Panics if site was not set on the question, or
+ /// site code not found in the map.
+ pub fn question_url<S>(&self, question: &Question<S>) -> String {
+ // answer link actually doesn't need question id
+ let question_id = question.id;
+ let site_url = self.site_url(question);
+ format!("https://{site_url}/q/{question_id}")
+ }
+
+ fn site_url<S>(&self, question: &Question<S>) -> String {
+ self.inner
+ .get(
+ question
+ .site
+ .as_ref()
+ .expect("bug: site not attached to question"),
+ )
+ .cloned()
+ .expect("bug: lost a site")
}
}