aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralyx <alyx@aleteoryx.me>2023-08-09 01:34:47 -0400
committeralyx <alyx@aleteoryx.me>2023-08-09 01:34:47 -0400
commit40372f0cf8a95f4d5bdf78fc522328b776482dbf (patch)
treed5c0b0ea655e685927ed6b96df777b28fb2856c2
parentd796f6762acb52cf2ab202d76382915064f0d534 (diff)
downloadlfm_embed-40372f0cf8a95f4d5bdf78fc522328b776482dbf.tar.gz
lfm_embed-40372f0cf8a95f4d5bdf78fc522328b776482dbf.tar.bz2
lfm_embed-40372f0cf8a95f4d5bdf78fc522328b776482dbf.zip
fix packages, implement caching
-rw-r--r--.gitignore1
-rw-r--r--Cargo.toml2
-rw-r--r--src/cache.rs120
-rw-r--r--src/deserialize.rs4
-rw-r--r--src/lib.rs3
5 files changed, 128 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index e1193dd..c97d769 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/Cargo.lock
/target
*~
.#*
diff --git a/Cargo.toml b/Cargo.toml
index ab70ee6..91dcbec 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+serde = { version = "1.0.183", features = ["derive", "rc", "alloc"] }
+serde_json = "1.0.104"
diff --git a/src/cache.rs b/src/cache.rs
new file mode 100644
index 0000000..9089ff1
--- /dev/null
+++ b/src/cache.rs
@@ -0,0 +1,120 @@
+use std::{future::Future, time::*, collections::HashMap, hash::Hash};
+
+pub struct AsyncCache<K, V, F> {
+ func: F,
+ cache: HashMap<K, (Instant, V)>,
+ interval: Duration
+}
+
+impl<K, V, F, Fut> AsyncCache<K, V, F>
+where
+ F: for<'a> FnMut(&'a K) -> Fut,
+ K: Hash + PartialEq + Eq + Clone,
+ Fut: Future<Output = Result<V, &'static str>>
+{
+ pub fn new(interval: Duration, mut func: F) -> Self {
+ Self{
+ cache: HashMap::new(),
+ interval, func
+ }
+ }
+
+ pub async fn get(&mut self, key: &K) -> Result<&V, &'static str> {
+ if self.is_stale(&key) {
+ self.renew(&key).await
+ } else {
+ Ok(&self.cache.get(&key).unwrap().1)
+ }
+ }
+
+ pub async fn renew(&mut self, key: &K) -> Result<&V, &'static str> {
+ let val = (self.func)(&key).await?;
+ self.cache.insert(key.clone(), (Instant::now(), val));
+ Ok(&self.cache.get(key).unwrap().1)
+ }
+
+ pub fn is_stale(&self, key: &K) -> bool {
+ if let Some((last_update, _)) = self.cache.get(key) {
+ let now = Instant::now();
+ now < (*last_update + self.interval)
+ }
+ else { true }
+ }
+
+ pub async fn get_opt(&self, key: &K) -> Option<&V> {
+ if self.is_stale(key) {
+ self.cache.get(key).map(|(_, v)| v)
+ }
+ else { None }
+ }
+}
+
+impl<K, V, F, Fut> AsyncCache<K, V, F>
+where
+ F: for<'a> FnMut(&'a K) -> Fut,
+ K: Hash + PartialEq + Eq + Clone,
+ V: Clone,
+ Fut: Future<Output = Result<V, &'static str>>
+{
+ pub async fn get_owned(&mut self, key: &K) -> Result<V, &'static str> {
+ self.get(key).await.cloned()
+ }
+}
+/*
+pub struct AsyncCache<K, V, F> {
+ func: F,
+ cache: HashMap<K, (Instant, V)>,
+ interval: Duration
+}
+
+impl<K, V, F> AsyncCache<K, V, F>
+where
+ for<'a> F: FnMut(&'a K) -> Fut + 'a,
+ Fut: Future<Output = V>
+{
+ pub fn new(interval: Duration, mut func: F) -> Self {
+ Self{
+ cache: HashMap::new(),
+ interval, func
+ }
+ }
+
+ pub async fn get(&mut self, key: &K) -> &V {
+ if self.is_stale(key) {
+ self.renew().await
+ } else {
+ self.cache.get(key)
+ }
+ }
+
+ pub async fn renew(&mut self, key: &K) -> &V {
+ self.cache.get_mut(key).0 = now;
+ self.cache.get_mut(key).1 = (self.func)(key).await;
+ self.cache.get(key)
+ }
+
+ pub fn is_stale(&self, key: &K) -> bool {
+ let now = Instant::now();
+ let last_update = self.cache.get(key).0;
+ now < (last_update + self.interval)
+ }
+
+ pub fn get_opt(&self, key: &K) -> Option<&T> {
+ if self.is_stale(key) {
+ Some(self.cache.get(key))
+ }
+ else { None }
+ }
+}
+
+impl<K, V, F> AsyncCache<K, V, F>
+where
+ F: for<'a> FnMut(&'a K) -> Fut + 'a,
+ Fut: Future<Output = V>,
+ V: Clone
+{
+ pub async fn get_owned(&mut self, key: &K) -> V {
+ self.get(key).await.clone()
+ }
+}
+*/
diff --git a/src/deserialize.rs b/src/deserialize.rs
index 4cedc9f..a00ebcb 100644
--- a/src/deserialize.rs
+++ b/src/deserialize.rs
@@ -74,8 +74,8 @@ pub struct Artist {
#[serde(default)]
#[serde(rename = "image")]
pub images: Vec<Image>,
- pub #[serde(default)]
- url: Option<Arc<str>>
+ #[serde(default)]
+ pub url: Option<Arc<str>>
}
#[derive(Deserialize, Debug)]
diff --git a/src/lib.rs b/src/lib.rs
index 5d0a682..87a87c5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1 +1,4 @@
+#![feature(entry_insert)]
+
mod deserialize;
+mod cache;