Skip to content

Bump cached from 0.49.3 to 2.0.2#80

Merged
AlexanderKlump merged 3 commits into
mainfrom
dependabot/cargo/cached-2.0.2
Jun 15, 2026
Merged

Bump cached from 0.49.3 to 2.0.2#80
AlexanderKlump merged 3 commits into
mainfrom
dependabot/cargo/cached-2.0.2

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 15, 2026

Copy link
Copy Markdown
Contributor

Bumps cached from 0.49.3 to 2.0.2.

Changelog

Sourced from cached's changelog.

[2.0.2]

  • Docs/tests only (no API change): document the Expires trait / expires = true as the idiomatic way to set a dynamic, per-entry TTL (a lifetime computed at call time rather than the uniform ttl = N), with a runnable example reference, and add a regression test for the runtime-argument-driven TTL case (#246).

[2.0.1]

  • Fix TtlSortedCacheBuilder: an explicit .capacity(n) is now honored even when .max_size(m) is also set. Previously the max_size-derived m + 1 preallocation ran first, and because HashMap::reserve never shrinks, a smaller .capacity(n) had no effect. The explicit capacity now takes precedence as the preallocation hint while max_size continues to bound entry count (#266).

[2.0.0 / cached_proc_macro 2.0.0]

Upgrading from 1.1? See the 2.0 migration guide.

Breaking Changes

Minimum supported Rust version & edition

  • MSRV raised from 1.80 to 1.85, and the crates moved to the 2024 edition. Edition 2024 was stabilized in Rust 1.85, so this is the new minimum a downstream project needs to build cached. Consumers already on Rust ≥ 1.85 are unaffected; those on 1.80–1.84 must update their toolchain. (The repository's rust-toolchain.toml pins the latest stable for local development and CI only — that pin does not propagate to consumers.)

Trait API changes

  • Cached::cache_remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>: new required method on the Cached trait that removes an entry and returns the stored key and value. Unlike cache_remove, this returns Some even when the deleted entry was already expired, making it possible to distinguish "key absent" from "key present but expired". Always fires the store's on_evict callback (if set).
  • ConcurrentCached::cache_remove_entry(&self, k: &K) -> Result<Option<(K, V)>, Self::Error>: same semantics on the concurrent trait; implemented for all nine concurrent stores (six sharded plus DiskCache / RedisCache / AsyncRedisCache). The seven non-sharded stores (UnboundCache, LruCache, etc.) gain cache_remove_entry via the Cached trait above.
  • Cached::cache_delete<Q>(&mut self, k: &Q) -> bool: new default method on Cached that deletes an entry without returning it; returns true if an entry was physically removed (including expired entries), false if the key was absent. Implemented via cache_remove_entry.
  • DiskCache and RedisCache / AsyncRedisCache now require K: Clone (in addition to existing bounds) for their ConcurrentCached / ConcurrentCachedAsync impls, which is needed to return the stored key from cache_remove_entry.
  • ConcurrentCached / ConcurrentCachedAsync mutators now take &self instead of &mut self: set_refresh_on_hit, set_ttl, and unset_ttl are defined with a shared receiver, matching the internally-synchronized &self contract of the rest of these traits (cache_set, cache_remove, …). This lets you flip the refresh flag or change the TTL on a shared store (e.g. one behind an Arc or a static) without exclusive access. Implementors must update their method signatures (fn set_ttl(&self, …) etc.); the bundled DiskCache / RedisCache / AsyncRedisCache stores do this via interior mutability (parking_lot::Mutex + AtomicBool). The single-owner Cached and CacheTtl traits are unaffected and keep their &mut self mutators.
  • ConcurrentCached::cache_size / ConcurrentCachedAsync::cache_size: new method fn cache_size(&self) -> Result<Option<usize>, Self::Error> reporting the number of entries, with a default of Ok(None). The default makes it non-breaking for existing external implementors and honest for stores that cannot cheaply produce a count: the six sharded stores override it to return Ok(Some(len)), while the external-store impls (DiskCache, RedisCache, AsyncRedisCache) keep the Ok(None) default because their backends (redb, Redis) expose no O(1) size. Sharded stores also retain their inherent len() / is_empty() for a non-Result count.

Macro attribute changes (#[cached], #[once], #[concurrent_cached])

  • result = true removed from #[cached] and #[once]: All Result<T, E> return types now automatically skip caching Err values. Remove result = true from all #[cached] and #[once] annotations — the behavior is now the default. To force-cache Err values, use the new cache_err = true opt-in.
  • option = true removed from #[cached] and #[once]: All Option<T> return types now automatically skip caching None values. Remove option = true from all #[cached] and #[once] annotations — the behavior is now the default. To force-cache None values, use the new cache_none = true opt-in.
  • #[concurrent_cached] now supports Option<T> returns: previously only Result<T, E> was accepted; Option<T> and plain T: Clone returns are now natively supported on the default in-memory sharded path. Note: option = true was never a recognized attribute on #[concurrent_cached] (it was silently ignored in 1.x); the new cache_none = true is the explicit opt-in to cache None values.
  • #[cached] / #[once] on fn() -> Option<T> without attributes: previously cached None as-is; now skips caching None. Add cache_none = true to preserve the old behavior.
  • #[cached] / #[once] on fn() -> Result<T,E> without attributes: previously cached the full Result; now skips caching Err. Add cache_err = true to preserve the old behavior.
  • result_fallback = true no longer requires result = true: the explicit result = true companion is dropped; result_fallback now auto-detects Result<T,E> return types.
  • Custom-ty users storing Option<T> or Result<T,E> directly: if your cache store type holds Option<T> or Result<T,E> as the value, you must now add cache_none = true or cache_err = true respectively so the macro uses the full wrapper type rather than extracting the inner T.
  • map_error on the default in-memory sharded path is now a compile error: previously map_error = "…" was silently accepted and ignored when the store was the infallible default. If you had map_error on a #[concurrent_cached] that uses no redis/disk/ty/create, remove it. If you still need map_error (because you are switching to a redis or disk backend), add the corresponding backend attribute.
  • result_fallback = true and with_cached_flag = true are mutually exclusive on #[concurrent_cached]: using both together is now a compile error. The combination was never valid — result_fallback stores the inner Ok(T) value while with_cached_flag wraps it in Return<T> — but the error was previously inscrutable. Remove one of the two attributes.
  • cache_none = true and with_cached_flag = true are mutually exclusive on #[cached], #[once], and #[concurrent_cached]: using both together is now a compile error. The combination was never valid — cache_none = true stores Option<T> as the cached value type while with_cached_flag = true stores the inner T — but the error was previously a confusing downstream type mismatch. Remove one of the two attributes.

Store behavior changes

  • cache_remove on expiring stores now returns None for expired-but-present entries. Previously ExpiringCache, ExpiringLruCache, and expiry-aware sharded stores returned Some(value) for an already-expired entry; now returns None. The entry is still removed and on_evict still fires.
  • ConcurrentCached::cache_delete (and its ConcurrentCachedAsync equivalent) now returns true for expired-but-physically-present entries. In 1.x the method returned false for such entries. Use cache_remove if you need to distinguish a live removal from an expired one.
  • LruCache::retain now fires on_evict and increments cache_evictions() for each removed entry, matching the semantics of cache_remove. Previously retain was side-effect-free. Internal TTL and expiring wrapper stores (LruTtlCache, ExpiringLruCache) use a new crate-internal retain_silent for their eviction sweeps, so those stores continue to count evictions exactly once.
  • DiskCacheBuildError gains a new InvalidTtl(BuildError) variant: any exhaustive match on DiskCacheBuildError must add an arm for InvalidTtl. This variant is returned when a DiskCacheBuilder is given a zero-duration TTL.
  • RedisCacheBuildError gains a new InvalidTtl(BuildError) variant: same as above for RedisCacheBuildError. Returned when a RedisCacheBuilder is given a zero-duration TTL.

Builder-only construction — build() returns Result, all store constructors removed

  • Every store is now built exactly one way: X::builder().…setters….build()?. All direct, store-returning constructors are removed — new, with_capacity, with_max_size, with_ttl, with_ttl_and_capacity, with_ttl_and_refresh, with_max_size_and_ttl, with_max_size_and_ttl_and_refresh, every try_with_*, and the sharded new / with_shards / with_max_size[_and_shards] / with_ttl[_and_shards] / with_max_size_and_ttl[_and_shards] variants — across UnboundCache, LruCache, TtlCache, LruTtlCache, TtlSortedCache, ExpiringCache, ExpiringLruCache, and all six sharded stores. (DiskCache / RedisCache / AsyncRedisCache are unchanged: their new(...) / builder(...) already return a builder.) This removes the second, panic-prone construction path that duplicated the builder.
  • Builder::build now returns Result<Store, BuildError> for every in-memory and sharded store. It previously returned the store directly and panicked on invalid configuration. Add ? or .unwrap(). (Disk/Redis build() already returned Result; unchanged.)
  • try_build() is removed from all builders. Now that build() is the single fallible constructor the alias is redundant — replace every .try_build() with .build().
  • TtlSortedCacheBuilder gains .capacity(n) — the preallocation hint formerly supplied via TtlSortedCache::with_ttl_and_capacity. It is distinct from .max_size(n), which is the eviction bound.
  • Zero TTL is now always rejected. Because every store is built through its (validating) builder, a zero Duration yields BuildError::InvalidTtl. The previously-permissive direct constructors (e.g. TtlCache::with_ttl(Duration::ZERO)) that accepted a zero TTL no longer exist.

sizemax_size naming (builder setter, macro attribute, runtime setters)

  • Builder setter .size(n).max_size(n) (LRU-family stores and TtlSortedCache). The sharded builders' per-shard cap setter is per_shard_max_size.

... (truncated)

Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file rust Pull requests that update Rust code labels Jun 15, 2026
Bumps [cached](https://github.com/jaemk/cached) from 0.49.3 to 2.0.2.
- [Changelog](https://github.com/jaemk/cached/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jaemk/cached/commits)

---
updated-dependencies:
- dependency-name: cached
  dependency-version: 2.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot force-pushed the dependabot/cargo/cached-2.0.2 branch from 338c26f to dd6ffe4 Compare June 15, 2026 12:36
@AlexanderKlump AlexanderKlump merged commit 418f367 into main Jun 15, 2026
7 checks passed
@dependabot dependabot Bot deleted the dependabot/cargo/cached-2.0.2 branch June 15, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant