summaryrefslogtreecommitdiff
path: root/service/src/cache.rs
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2026-02-07 17:29:48 +0100
committerDawid Rycerz <dawid@rycerz.xyz>2026-02-07 17:29:48 +0100
commit2eda97537b63d68b2e9ba06500e3fb491894d10c (patch)
tree52873ad380cd97f4327765aac24659a2b00079b1 /service/src/cache.rs
feat: camper van energy monitoring widget for Plasma 6main
Pure QML KPackage widget with Rust background service for real-time Victron energy system monitoring via MQTT and D-Bus. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'service/src/cache.rs')
-rw-r--r--service/src/cache.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/service/src/cache.rs b/service/src/cache.rs
new file mode 100644
index 0000000..acaf9d3
--- /dev/null
+++ b/service/src/cache.rs
@@ -0,0 +1,63 @@
+use std::{
+ path::PathBuf,
+ time::{Duration, SystemTime},
+};
+
+use anyhow::{Result, anyhow};
+
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
+struct SerialCacheEntry {
+ serial: String,
+ expires_at_unix: u64,
+}
+
+fn cache_file_path() -> Result<PathBuf> {
+ let proj_dir = dirs::cache_dir()
+ .ok_or_else(|| anyhow!("No cache dir"))?
+ .join("camper-widget-refresh");
+ Ok(proj_dir.join("serial.json"))
+}
+
+pub async fn read_serial_cache() -> Result<Option<String>> {
+ let path = cache_file_path()?;
+ if !path.exists() {
+ return Ok(None);
+ }
+ let content = tokio::fs::read_to_string(&path)
+ .await
+ .map_err(|e| anyhow!("Failed to read cache file at {}: {}", path.display(), e))?;
+ let entry: SerialCacheEntry = serde_json::from_str(&content)?;
+ let now = SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)?
+ .as_secs();
+ if now <= entry.expires_at_unix {
+ Ok(Some(entry.serial))
+ } else {
+ Ok(None)
+ }
+}
+
+pub async fn write_serial_cache(serial: &str, ttl: Duration) -> Result<()> {
+ let path = cache_file_path()?;
+ if let Some(parent) = path.parent() {
+ tokio::fs::create_dir_all(parent).await.map_err(|e| {
+ anyhow!(
+ "Failed to create cache directory {}: {}",
+ parent.display(),
+ e
+ )
+ })?;
+ }
+ let now = SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)?
+ .as_secs();
+ let entry = SerialCacheEntry {
+ serial: serial.to_string(),
+ expires_at_unix: now + ttl.as_secs(),
+ };
+ let data = serde_json::to_string(&entry)?;
+ tokio::fs::write(&path, data)
+ .await
+ .map_err(|e| anyhow!("Failed to write cache file at {}: {}", path.display(), e))?;
+ Ok(())
+}