Skip to main content

CacheStore

Struct CacheStore 

Source
pub struct CacheStore { /* private fields */ }
Expand description

JSON-file cache with atomic (temp + rename) writes and an in-memory mirror.

Implementations§

Source§

impl CacheStore

Source

pub fn new(path: impl Into<PathBuf>) -> Self

Source

pub fn at_default_path() -> Self

Source

pub fn disabled() -> Self

Non-persistent store: get always misses, put and flush are no-ops. Used for --demo and tests — demo data is canned, so caching it would only leak between runs.

Source

pub async fn load(&self)

Hydrate the in-memory map from disk. Never fails the caller: a missing, unreadable, corrupt or version-mismatched file leaves the store empty and logs a line.

Source

pub fn get<T: DeserializeOwned>(&self, key: &str) -> Option<CacheEntry<T>>

Read a cached value. None on a miss, and on a deserialize failure — a domain type whose shape changed since the entry was written must degrade to a miss, not an error.

There is deliberately no read-time TTL: an entry is returned however old it is. Callers paint stale data on purpose and surface its age in the UI. Expiring on read would hand the caller a blank screen again, which is the exact problem this cache exists to remove.

Source

pub fn put<T: Serialize>( &self, key: &str, value: &T, fetched_at: DateTime<Utc>, ) -> CachePut

Write through, reporting what happened.

Refuses (CachePut::Stale, mutating nothing) when an entry already exists whose fetched_at is newer than or equal to this one. Responses do not come back in the order they were sent: a slow request started before a fast one can land after it, and without this guard it would quietly overwrite fresh data with stale.

Source

pub fn rewrite<T: Serialize + DeserializeOwned>( &self, key: &str, edit: impl FnOnce(T) -> T, ) -> bool

Edits an entry already in the store, keeping its fetched_at.

put is for “here is a fresher response”, and its staleness guard compares timestamps — so it refuses a write carrying the entry’s own fetched_at, which is exactly what editing a cached list in place has to do. This is the seam for that: dropping rows from a list is not new data and must not be dated as if it were, or the staleness indicator would report an hours-old list as current.

Returns whether anything was written. A missing key is a no-op, and so is an entry that was replaced by a real fetch while edit ran — that response is newer than this edit and owns the key.

Source

pub async fn flush(&self)

Persist to disk if dirty, atomically. Errors are logged, never propagated; the dirty flag survives a failed write so the next flush retries rather than losing the entries.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.