Add example of passing dyn trait instance#236
Open
breadrock1 wants to merge 2 commits into
Open
Conversation
…e caching structure methods is unavailable
jaemk
added a commit
that referenced
this pull request
Jun 9, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; the redis/disk macro paths use the borrowed setter to avoid an extra clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release on publish (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 9, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; the redis/disk macro paths use the borrowed setter to avoid an extra clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release on publish (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 9, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; the redis/disk macro paths use the borrowed setter to avoid an extra clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release on publish (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 9, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; the redis/disk macro paths use the borrowed setter to avoid an extra clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 10, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; the redis/disk macro paths use the borrowed setter to avoid an extra clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 10, 2026
…ext major) Second tranche of the next major (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245) - fix a doctest under `--no-default-features` (#260) See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 10, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149) - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat) (#146) - `in_impl` attribute to cache methods inside `impl` blocks / `self` receivers (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; `in_impl` emits a same-visibility `{fn}_no_cache` cache-bypass sibling; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; Redis whole-second `ttl_millis` rounding; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry; `CachedAsync` shared-ref default Send bounds; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh`; `#[once]` `force_refresh`; generic `in_impl` rejection golden; `TtlSortedCache` shared-ref get-or-set delegation See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 10, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149); rejected alongside a `create` block like the other store-builder attributes - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat) (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a same-visibility `{fn}_no_cache` cache-bypass sibling (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear` (#200) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache (#180) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236) - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a same-visibility `{fn}_no_cache` sibling (documented on all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry, including how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh`; `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic `in_impl` rejection golden; compile-fail goldens for `force_refresh`-unparseable on `#[once]` / `#[concurrent_cached]`, generic `#[concurrent_cached]` without `convert`, and `ttl_millis` + `create` conflict; `TtlSortedCache` shared-ref get-or-set delegation - macro-output polish: no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 11, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149); rejected alongside a `create` block like the other store-builder attributes - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - dev tooling: pr-review shards reviewers across model-sized, randomized chunks (multiple of each type); pr-cycle fans fix application across disjoint sub-agents; AGENTS.md states README is generated from src/lib.rs via cargo-readme - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (documented on all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]` (ttl_millis / force_refresh / in_impl rows); wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry, including how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic `in_impl` rejection goldens for `#[cached]` (free fn) and `#[concurrent_cached]` (in_impl method); compile-fail goldens for `force_refresh`-unparseable on `#[once]` / `#[concurrent_cached]`, generic `#[concurrent_cached]` without `convert`, and `ttl_millis` + `create` conflict; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; `TtlSortedCache` shared-ref get-or-set delegation - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 11, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149); rejected alongside a `create` block like the other store-builder attributes - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - dev tooling: pr-review shards reviewers across model-sized, randomized chunks (multiple of each type); pr-cycle fans fix application across disjoint sub-agents; AGENTS.md states README is generated from src/lib.rs via cargo-readme - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (documented on all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]` (ttl_millis / force_refresh / in_impl rows); wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry, including how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic `in_impl` rejection goldens for `#[cached]` (free fn) and `#[concurrent_cached]` (in_impl method); compile-fail goldens for `force_refresh`-unparseable on `#[once]` / `#[concurrent_cached]`, generic `#[concurrent_cached]` without `convert`, and `ttl_millis` + `create` conflict; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; `TtlSortedCache` shared-ref get-or-set delegation - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 11, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149); rejected alongside a `create` block like the other store-builder attributes - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - dev tooling: pr-review shards reviewers across model-sized, randomized chunks (multiple of each type); pr-cycle fans fix application across disjoint sub-agents; AGENTS.md states README is generated from src/lib.rs via cargo-readme - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (documented on all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]` (ttl_millis / force_refresh / in_impl rows); wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry, including how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic `in_impl` rejection goldens for `#[cached]` (free fn) and `#[concurrent_cached]` (in_impl method); compile-fail goldens for `force_refresh`-unparseable on `#[once]` / `#[concurrent_cached]`, generic `#[concurrent_cached]` without `convert`, and `ttl_millis` + `create` conflict; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; `TtlSortedCache` shared-ref get-or-set delegation - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 11, 2026
…ext major) Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups. Macros: - `ttl_millis` attribute for sub-second TTLs, mutually exclusive with `ttl` (#149); rejected alongside a `create` block like the other store-builder attributes - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - dev tooling: pr-review shards reviewers across model-sized, randomized chunks (multiple of each type); pr-cycle fans fix application across disjoint sub-agents; AGENTS.md states README is generated from src/lib.rs via cargo-readme - documentation accuracy pass: `ttl_millis` is valid with `result_fallback` and (on the in-memory path) needs `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (documented on all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]` (ttl_millis / force_refresh / in_impl rows); wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the `in_impl` shared-cache footgun; the async `V: Sync` clone-elision asymmetry, including how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat - added coverage: async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic `in_impl` rejection goldens for `#[cached]` (free fn) and `#[concurrent_cached]` (in_impl method); compile-fail goldens for `force_refresh`-unparseable on `#[once]` / `#[concurrent_cached]`, generic `#[concurrent_cached]` without `convert`, and `ttl_millis` + `create` conflict; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; `TtlSortedCache` shared-ref get-or-set delegation - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 13, 2026
…or + ttl consistency Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups, including a consumer-experience pass that made constructors and the ttl attribute consistent across the public surface. Macros: - `ttl` attribute now takes a `Duration` expression (`ttl = "core::time::Duration::from_secs(60)"`); the old whole-seconds integer form (`ttl = 60`) is removed and emits a migration error pointing at `ttl_secs`/`ttl_millis` - `ttl_secs` attribute for whole-second TTLs and `ttl_millis` for sub-second TTLs; `ttl` / `ttl_secs` / `ttl_millis` are three-way mutually exclusive, and each is mutually exclusive with `expires` (#149) - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - `refresh` is rejected alongside the other store-builder attributes when a `create` block is supplied, mirroring `#[concurrent_cached]` - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - every in-memory and sharded store gains a `new()` that returns a ready-to-use cache (zero-config stores take no args; required-field stores take them positionally - `LruCache::new(max_size)`, `TtlCache::new(ttl)`, `LruTtlCache::new(max_size, ttl)`, the `Sharded*` variants, etc.), all `#[must_use]`. `RedbCache` / `RedisCache` / `AsyncRedisCache` drop `new()` (it returned a builder, not a cache); use `builder(...)`. `new()` now consistently returns a usable cache everywhere it exists - every TTL builder (non-sharded, sharded, Redis, Redb) gains `ttl_secs` / `ttl_millis` convenience setters alongside `ttl(Duration)`; last-writer-wins - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - docs and examples now prefer the short alias method API (`get`/`set`/`remove`/`clear`/`len`/...) over the `cache_*`-prefixed forms, with a note (in the crate docs and on the `Cached` trait) on when to use the `cache_*` names - a collision with another in-scope trait's method. Both forms remain; no method was removed - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` and noting the in_impl cache is not externally invalidatable and its shared-id staleness footgun - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); it retries a missing release when the tag already exists on the remote; the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - README is generated from src/lib.rs via cargo-readme (regenerated here); dev tooling: pr-review shards reviewers across model-sized randomized chunks; pr-cycle fans fix application across disjoint sub-agents - documentation accuracy pass: `ttl_millis` / `ttl_secs` are valid with `result_fallback` and (on the in-memory path) need `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]`; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the async `V: Sync` clone-elision asymmetry and how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat; redis `build()` lists `InvalidTtl` before `EmptyScope` to match validation order - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback Tests: - positive macro coverage for all three ttl spellings (`ttl` Duration expr / `ttl_secs` / `ttl_millis`) across `#[cached]` / `#[once]` / `#[concurrent_cached]`, and compile-fail UI goldens for the three-way exclusivity and the `ttl = <int>` migration error - inline store coverage for every new `new()` constructor and the `ttl_secs` / `ttl_millis` builder setters (including override semantics) - async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic-rejection goldens; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; deferred attribute/store combinations (max_size+ttl_millis, in_impl+ttl_millis, ttl_millis+force_refresh, result_fallback+ttl_millis, async once in_impl) and store(0) counter resets; sharded peek does not renew TTL under refresh_on_hit See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 14, 2026
…or + ttl consistency Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups, including a consumer-experience pass that made constructors and the ttl attribute consistent across the public surface. Macros: - `ttl` attribute now takes a `Duration` expression (`ttl = "core::time::Duration::from_secs(60)"`); the old whole-seconds integer form (`ttl = 60`) is removed and emits a migration error pointing at `ttl_secs`/`ttl_millis` - `ttl_secs` attribute for whole-second TTLs and `ttl_millis` for sub-second TTLs; `ttl` / `ttl_secs` / `ttl_millis` are three-way mutually exclusive, and each is mutually exclusive with `expires` (#149) - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - `refresh` is rejected alongside the other store-builder attributes when a `create` block is supplied, mirroring `#[concurrent_cached]` - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - every in-memory and sharded store gains a `new()` that returns a ready-to-use cache (zero-config stores take no args; required-field stores take them positionally - `LruCache::new(max_size)`, `TtlCache::new(ttl)`, `LruTtlCache::new(max_size, ttl)`, the `Sharded*` variants, etc.), all `#[must_use]`. `RedbCache` / `RedisCache` / `AsyncRedisCache` drop `new()` (it returned a builder, not a cache); use `builder(...)`. `new()` now consistently returns a usable cache everywhere it exists - `new()` / `builder()` on each sharded `*Base` type are now defined only on the default-hasher specialization (`*Base<K, V, DefaultShardHasher>`, the named alias). They previously sat on the generic `*Base<K, V, H>` impl but always returned a `DefaultShardHasher` builder, so a `*Base::<_, _, CustomHasher>:: builder()` / `::new()` turbofish compiled yet silently dropped the custom hasher; that turbofish now fails to compile (E0599). A custom hasher is specified via `ShardedX::builder().hasher(h)`, which switches the builder's hasher type; alias-based construction and the `.hasher()` path are unchanged - every TTL builder (non-sharded, sharded, Redis, Redb) gains `ttl_secs` / `ttl_millis` convenience setters alongside `ttl(Duration)`; last-writer-wins - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - docs and examples now prefer the short alias method API (`get`/`set`/`remove`/`clear`/`len`/...) over the `cache_*`-prefixed forms, with a note (in the crate docs and on the `Cached` trait) on when to use the `cache_*` names - a collision with another in-scope trait's method. Both forms remain; no method was removed - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` and noting the in_impl cache is not externally invalidatable and its shared-id staleness footgun - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); it retries a missing release when the tag already exists on the remote; the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - README is generated from src/lib.rs via cargo-readme (regenerated here); dev tooling: pr-review shards reviewers across model-sized randomized chunks; pr-cycle fans fix application across disjoint sub-agents - documentation accuracy pass: `ttl_millis` / `ttl_secs` are valid with `result_fallback` and (on the in-memory path) need `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]`; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the async `V: Sync` clone-elision asymmetry and how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat; redis `build()` lists `InvalidTtl` before `EmptyScope` to match validation order - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback - elevate all compiler warnings to errors workspace-wide via the Cargo `[lints]` table (`[workspace.lints.rust] warnings = "deny"`, opted into by the `cached` and `cached_proc_macro` packages), so `cargo build`/`test`/`clippy` deny warnings rather than only the Makefile clippy target; gate `validate_ttl` to `any(time_stores, disk_store, redis_store)` and an unused test `AtomicUsize` import to `proc_macro` to keep `--no-default-features` warning-clean Tests: - positive macro coverage for all three ttl spellings (`ttl` Duration expr / `ttl_secs` / `ttl_millis`) across `#[cached]` / `#[once]` / `#[concurrent_cached]`, and compile-fail UI goldens for the three-way exclusivity and the `ttl = <int>` migration error - inline store coverage for every new `new()` constructor and the `ttl_secs` / `ttl_millis` builder setters (including override semantics) - compile-fail UI golden asserting `*Base::<_, _, CustomHasher>::{new,builder}()` no longer compiles (the custom-hasher `.hasher()` path stays covered by the existing sharded `custom_hasher` unit test) - async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic-rejection goldens; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; deferred attribute/store combinations (max_size+ttl_millis, in_impl+ttl_millis, ttl_millis+force_refresh, result_fallback+ttl_millis, async once in_impl) and store(0) counter resets; sharded peek does not renew TTL under refresh_on_hit See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 20, 2026
…or + ttl consistency Next-major batch (after the redb DiskCache rewrite). Bundles a set of breaking and additive changes plus the doc/test follow-ups, including a consumer-experience pass that made constructors and the ttl attribute consistent across the public surface. Macros: - `ttl` attribute now takes a `Duration` expression (`ttl = "core::time::Duration::from_secs(60)"`); the old whole-seconds integer form (`ttl = 60`) is removed and emits a migration error pointing at `ttl_secs`/`ttl_millis` - `ttl_secs` attribute for whole-second TTLs and `ttl_millis` for sub-second TTLs; `ttl` / `ttl_secs` / `ttl_millis` are three-way mutually exclusive, and each is mutually exclusive with `expires` (#149) - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - `refresh` is rejected alongside the other store-builder attributes when a `create` block is supplied, mirroring `#[concurrent_cached]` - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - every in-memory and sharded store gains a `new()` that returns a ready-to-use cache (zero-config stores take no args; required-field stores take them positionally - `LruCache::new(max_size)`, `TtlCache::new(ttl)`, `LruTtlCache::new(max_size, ttl)`, the `Sharded*` variants, etc.), all `#[must_use]`. `RedbCache` / `RedisCache` / `AsyncRedisCache` drop `new()` (it returned a builder, not a cache); use `builder(...)`. `new()` now consistently returns a usable cache everywhere it exists - `new()` / `builder()` on each sharded `*Base` type are now defined only on the default-hasher specialization (`*Base<K, V, DefaultShardHasher>`, the named alias). They previously sat on the generic `*Base<K, V, H>` impl but always returned a `DefaultShardHasher` builder, so a `*Base::<_, _, CustomHasher>:: builder()` / `::new()` turbofish compiled yet silently dropped the custom hasher; that turbofish now fails to compile (E0599). A custom hasher is specified via `ShardedX::builder().hasher(h)`, which switches the builder's hasher type; alias-based construction and the `.hasher()` path are unchanged - every TTL builder (non-sharded, sharded, Redis, Redb) gains `ttl_secs` / `ttl_millis` convenience setters alongside `ttl(Duration)`; last-writer-wins - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - docs and examples now prefer the short alias method API (`get`/`set`/`remove`/`clear`/`len`/...) over the `cache_*`-prefixed forms, with a note (in the crate docs and on the `Cached` trait) on when to use the `cache_*` names - a collision with another in-scope trait's method. Both forms remain; no method was removed - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` and noting the in_impl cache is not externally invalidatable and its shared-id staleness footgun - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); it retries a missing release when the tag already exists on the remote; the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - README is generated from src/lib.rs via cargo-readme (regenerated here); dev tooling: pr-review shards reviewers across model-sized randomized chunks; pr-cycle fans fix application across disjoint sub-agents - documentation accuracy pass: `ttl_millis` / `ttl_secs` are valid with `result_fallback` and (on the in-memory path) need `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]`; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the async `V: Sync` clone-elision asymmetry and how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat; redis `build()` lists `InvalidTtl` before `EmptyScope` to match validation order - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback - elevate all compiler warnings to errors workspace-wide via the Cargo `[lints]` table (`[workspace.lints.rust] warnings = "deny"`, opted into by the `cached` and `cached_proc_macro` packages), so `cargo build`/`test`/`clippy` deny warnings rather than only the Makefile clippy target; gate `validate_ttl` to `any(time_stores, disk_store, redis_store)` and an unused test `AtomicUsize` import to `proc_macro` to keep `--no-default-features` warning-clean Tests: - positive macro coverage for all three ttl spellings (`ttl` Duration expr / `ttl_secs` / `ttl_millis`) across `#[cached]` / `#[once]` / `#[concurrent_cached]`, and compile-fail UI goldens for the three-way exclusivity and the `ttl = <int>` migration error - inline store coverage for every new `new()` constructor and the `ttl_secs` / `ttl_millis` builder setters (including override semantics) - compile-fail UI golden asserting `*Base::<_, _, CustomHasher>::{new,builder}()` no longer compiles (the custom-hasher `.hasher()` path stays covered by the existing sharded `custom_hasher` unit test) - async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic-rejection goldens; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; deferred attribute/store combinations (max_size+ttl_millis, in_impl+ttl_millis, ttl_millis+force_refresh, result_fallback+ttl_millis, async once in_impl) and store(0) counter resets; sharded peek does not renew TTL under refresh_on_hit See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
jaemk
added a commit
that referenced
this pull request
Jun 20, 2026
…sistency Make constructors and the ttl attribute consistent across the public surface, on top of the redb DiskCache rewrite. Breaking and additive changes with doc and test follow-ups: Macros: - `ttl` attribute now takes a `Duration` expression (`ttl = "core::time::Duration::from_secs(60)"`); the old whole-seconds integer form (`ttl = 60`) is removed and emits a migration error pointing at `ttl_secs`/`ttl_millis` - `ttl_secs` attribute for whole-second TTLs and `ttl_millis` for sub-second TTLs; `ttl` / `ttl_secs` / `ttl_millis` are three-way mutually exclusive, and each is mutually exclusive with `expires` (#149) - `force_refresh` attribute to bypass the cache per call, on all three macros (`#[cached]` / `#[concurrent_cached]` / `#[once]`); on `#[once]` it overwrites the single shared value (no per-call key, so no key-exclusion caveat). Combined with `result_fallback`, a force-refreshed `Err` still serves the previously cached `Ok`, and capturing that fallback leaves no read side effects on the bypassed entry (no TTL renewal, recency update, or hit-counter change) on both `#[cached]` and `#[concurrent_cached]` (#146) - `in_impl` attribute to cache methods inside `impl` blocks; `self`-receiver methods require `in_impl` (a `convert` block alone cannot rescue them, since the cache static cannot live at `impl` scope) and emit a `{fn}_no_cache` cache-bypass sibling, hidden from rustdoc via `#[doc(hidden)]` (#16, #140) - reference arguments (`&T`, `Option<&T>`) form the default key without `convert` (#202, #203) - generated code resolves the crate path via `proc-macro-crate`, so a renamed or re-exported `cached` dependency works (#157) - macro-introduced bindings are hygienically named, so arguments named `key` / `cache` / `result` no longer collide with generated code (#230, #114) - clear compile error for generic functions used without `key` + `convert` (#80) - `refresh` is rejected alongside the other store-builder attributes when a `create` block is supplied, mirroring `#[concurrent_cached]` - the shared `force_refresh` guard builder is factored into one helper Traits and stores: - every in-memory and sharded store gains a `new()` that returns a ready-to-use cache (zero-config stores take no args; required-field stores take them positionally - `LruCache::new(max_size)`, `TtlCache::new(ttl)`, `LruTtlCache::new(max_size, ttl)`, the `Sharded*` variants, etc.), all `#[must_use]`. `RedbCache` / `RedisCache` / `AsyncRedisCache` drop `new()` (it returned a builder, not a cache); use `builder(...)`. `new()` now consistently returns a usable cache everywhere it exists - `new()` / `builder()` on each sharded `*Base` type are now defined only on the default-hasher specialization (`*Base<K, V, DefaultShardHasher>`, the named alias). They previously sat on the generic `*Base<K, V, H>` impl but always returned a `DefaultShardHasher` builder, so a `*Base::<_, _, CustomHasher>:: builder()` / `::new()` turbofish compiled yet silently dropped the custom hasher; that turbofish now fails to compile (E0599). A custom hasher is specified via `ShardedX::builder().hasher(h)`, which switches the builder's hasher type; alias-based construction and the `.hasher()` path are unchanged - every TTL builder (non-sharded, sharded, Redis, Redb) gains `ttl_secs` / `ttl_millis` convenience setters alongside `ttl(Duration)`; last-writer-wins - `get_or_set_with` / `try_get_or_set_with` (and the async variants) now return `&V` instead of `&mut V`, with new `*_mut` variants preserving the old behavior (#179) - new additive `SerializeCached` / `SerializeCachedAsync` traits (`cache_set_ref`) for serialize-backed stores; `#[concurrent_cached]` routes its set through an autoref shim that uses the borrowed setter for any store implementing the trait (built-in redis/disk or a custom `ty`/`create` store), avoiding a value clone (#196, #195) - `RedisCache` / `AsyncRedisCache` gain `cache_clear` / `async_cache_clear`, with `cache_reset` delegating to `cache_clear`; `RedisCacheBuilder` / `AsyncRedisCacheBuilder` `build()` reject an empty namespace+prefix scope (`EmptyScope`) so `cache_clear` cannot `SCAN MATCH *` the whole database (#200) - `RedbCacheBuilder::build()` validates `cache_name` as a filename component, returning `InvalidCacheName` for a path separator (`/` or `\`) or a path-traversal component (`.` / `..`) - `LruCache::set_max_size` / `try_set_max_size` for resizing a live cache, with matching methods on `LruTtlCache` and `ExpiringLruCache` (#180) - `ConcurrentCloneCached` gains a non-renewing `cache_peek_with_expiry_status` (used to capture a `result_fallback` stale value without read side effects) Redis: - TLS features split so rustls is selectable; `redis_tokio` / `redis_smol` no longer imply native-tls (add `*_native_tls` or `*_rustls`) (#231) Docs and process: - docs and examples now prefer the short alias method API (`get`/`set`/`remove`/`clear`/`len`/...) over the `cache_*`-prefixed forms, with a note (in the crate docs and on the `Cached` trait) on when to use the `cache_*` names - a collision with another in-scope trait's method. Both forms remain; no method was removed - document floats as the canonical `convert` case (#78); add cache-invalidation and struct-method examples (#21, #236), the latter demonstrating `in_impl` and noting the in_impl cache is not externally invalidatable and its shared-id staleness footgun - release workflow tags and creates a GitHub release for each published workspace crate on publish, via `bin/tag-release.sh` (root `cached` -> `vX.Y.Z`, subcrates -> `<crate-name>-vX.Y.Z`) (#245); it retries a missing release when the tag already exists on the remote; the CI tag-release git identity is scoped to `--local` - fix a doctest under `--no-default-features` (#260) - exclude internal dev tooling (.agents, .claude, .github, bin, docs/dev, AGENTS.md, CLAUDE.md) from the published crate via Cargo `exclude` - README is generated from src/lib.rs via cargo-readme (regenerated here); dev tooling: pr-review shards reviewers across model-sized randomized chunks; pr-cycle fans fix application across disjoint sub-agents - documentation accuracy pass: `ttl_millis` / `ttl_secs` are valid with `result_fallback` and (on the in-memory path) need `time_stores`; on `#[cached]` the "honored exactly" claim is scoped to the default in-memory store; Redis rounds `ttl_millis` up to the next whole second (500ms -> 1s, 1500ms -> 2s); `in_impl` emits a `#[doc(hidden)]` `{fn}_no_cache` sibling (all three macros); `#[concurrent_cached]` `force_refresh` documents the `result_fallback` interaction; the `#[concurrent_cached]` attribute table reaches parity with `#[cached]`; wasm is incompatible with `redis_connection_manager` / `redis_async_cache`; the async `V: Sync` clone-elision asymmetry and how a `Send + !Sync + !Clone` value surfaces at the generated set site; `CachedAsync` shared-ref default Send bounds; `Cached::cache_get_or_set_with` / `cache_try_get_or_set_with` flagged as provided defaults; migration-guide `&mut V` -> `&V` coercion caveat; redis `build()` lists `InvalidTtl` before `EmptyScope` to match validation order - macro-output polish: ASCII-only macro diagnostics; no dead `#[doc]` on the function-local `in_impl` cache static; documented rationale for `#[allow(dead_code)]` on the generated prime companion and for the `crate_path()` `::cached` fallback - elevate all compiler warnings to errors workspace-wide via the Cargo `[lints]` table (`[workspace.lints.rust] warnings = "deny"`, opted into by the `cached` and `cached_proc_macro` packages), so `cargo build`/`test`/`clippy` deny warnings rather than only the Makefile clippy target; gate `validate_ttl` to `any(time_stores, disk_store, redis_store)` and an unused test `AtomicUsize` import to `proc_macro` to keep `--no-default-features` warning-clean Tests: - positive macro coverage for all three ttl spellings (`ttl` Duration expr / `ttl_secs` / `ttl_millis`) across `#[cached]` / `#[once]` / `#[concurrent_cached]`, and compile-fail UI goldens for the three-way exclusivity and the `ttl = <int>` migration error - inline store coverage for every new `new()` constructor and the `ttl_secs` / `ttl_millis` builder setters (including override semantics) - compile-fail UI golden asserting `*Base::<_, _, CustomHasher>::{new,builder}()` no longer compiles (the custom-hasher `.hasher()` path stays covered by the existing sharded `custom_hasher` unit test) - async clone-elision clone-count assertions; `#[concurrent_cached]` `result_fallback` + `force_refresh` (including the no-read-side-effects bypass); `#[once]` `force_refresh`; `force_refresh` + `in_impl`; generic-rejection goldens; `_mut` trait coverage on `ExpiringCache` / `TtlSortedCache`; redis `cache_clear` / `cache_set_ref` and redb `cache_set_ref` round-trips; deferred attribute/store combinations (max_size+ttl_millis, in_impl+ttl_millis, ttl_millis+force_refresh, result_fallback+ttl_millis, async once in_impl) and store(0) counter resets; sharded peek does not renew TTL under refresh_on_hit See docs/migrations/2.0-to-unreleased.md and the CHANGELOG for migration details.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey!
Stuck when trying to cache result method data from structure method. Compiler prints out message like cached crate does not support caching structure methods. Then I have tried pass trait instance of current object as generic type - the same limitations...
There is no any example of this problem solution, so i think it's may be useful example for users 😃