cultcache-rs: name, index and global lookups (C# parity) #15

Merged
libby merged 3 commits from libby/cultcache-rs-lookups into main 2026-11-07 12:12:05 +00:00
Member

Rust CultCache lookups parity with C# GetByName / GetByIndex / GetGlobal (src/GameCult.Caching/CultCache.cs).

  • Derive: #[cultcache(name)], #[cultcache(index)] / #[cultcache(index = "alias")] on fields, #[cultcache(global)] on the struct. A blank alias is the member name (C# ResolveIndexAlias). Two index members with one alias are a compile error (C# D10). Lookup attributes are refused on CultSlots.
  • Cache: get_by_name, get_by_index, get_global. Empty name / blank index value are not found. Records of one type sharing a value find the smallest key (ordinal), live and after reopen; removing the holder finds the next.
  • Global: a second record of a global type under another key is a typed CultCacheSecondGlobal refusal (C# message) on put, put_envelope, put_raw_envelope, put_prepared_batch, and on pull_all / load_soa; nothing is written.
  • Lookups scan the type's entries in key order (no side index to go stale), decoding each; O(records of the type) per call.

Deviations from C#, for review:

  1. Name duplicates: C# keeps last-writer-wins and loses the name when the latest holder is removed (write-order dependent). Rust finds the smallest key, as C# does for indexes.
  2. Two #[cultcache(name)] members: C# silently takes the first; Rust refuses at compile time.
  3. No subtype lookups (IsAssignableFrom ambiguity refusals) and no variants: Rust has neither.
  4. No default global:<schemaId> key: Rust put always takes a key.
  5. Schema catalog is unchanged (this runtime writes no member descriptions, so IsName/IndexAlias are not published).

Tests: tests/lookups.rs (16), derive unit tests (+7). Ported from FirstCallTests, BackingStoreTests (HydratesPersistedGlobal), RetypeEvictionTests (global slot), VariantTests (duplicate-holder removal), StoreRouting (two globals refused). Each rule was mutated and a test failed.

🤖 Generated with Claude Code

Rust CultCache lookups parity with C# `GetByName` / `GetByIndex` / `GetGlobal` (`src/GameCult.Caching/CultCache.cs`). - Derive: `#[cultcache(name)]`, `#[cultcache(index)]` / `#[cultcache(index = "alias")]` on fields, `#[cultcache(global)]` on the struct. A blank alias is the member name (C# `ResolveIndexAlias`). Two index members with one alias are a compile error (C# D10). Lookup attributes are refused on `CultSlots`. - Cache: `get_by_name`, `get_by_index`, `get_global`. Empty name / blank index value are not found. Records of one type sharing a value find the smallest key (ordinal), live and after reopen; removing the holder finds the next. - Global: a second record of a global type under another key is a typed `CultCacheSecondGlobal` refusal (C# message) on put, put_envelope, put_raw_envelope, put_prepared_batch, and on pull_all / load_soa; nothing is written. - Lookups scan the type's entries in key order (no side index to go stale), decoding each; O(records of the type) per call. Deviations from C#, for review: 1. Name duplicates: C# keeps last-writer-wins and loses the name when the latest holder is removed (write-order dependent). Rust finds the smallest key, as C# does for indexes. 2. Two `#[cultcache(name)]` members: C# silently takes the first; Rust refuses at compile time. 3. No subtype lookups (`IsAssignableFrom` ambiguity refusals) and no variants: Rust has neither. 4. No default `global:<schemaId>` key: Rust `put` always takes a key. 5. Schema catalog is unchanged (this runtime writes no member descriptions, so IsName/IndexAlias are not published). Tests: `tests/lookups.rs` (16), derive unit tests (+7). Ported from FirstCallTests, BackingStoreTests (HydratesPersistedGlobal), RetypeEvictionTests (global slot), VariantTests (duplicate-holder removal), StoreRouting (two globals refused). Each rule was mutated and a test failed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
#[cultcache(name)], #[cultcache(index[ = alias])] and struct-level #[cultcache(global)]
in the DatabaseEntry derive; get_by_name, get_by_index and get_global on CultCache; a
second record of a global type under another key is a typed CultCacheSecondGlobal refusal
on every write path and on load.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
cultcache-rs: lookups cross-type test, changelog and README entries
Some checks failed
CultMesh QUIC native / Build win32-x64 (pull_request) Has been skipped
CultMesh QUIC native / Build linux-x64 (pull_request) Has been skipped
CultMesh QUIC native / Release native binaries (pull_request) Has been skipped
CultMesh portability and performance / ubuntu-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / ubuntu-latest reactive semantics and leases (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest reactive semantics and leases (pull_request) Has been cancelled
CultNet cross-runtime interop / C# / TypeScript / Rust / Python / Kotlin (pull_request) Has been cancelled
CultMesh QUIC native / Verify committed binaries match SHA256SUMS (pull_request) Has been cancelled
95d8be34a7
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libby merged commit cf0d93d091 into main 2026-11-07 12:12:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/CultLib!15
No description provided.