import: a .rsbank lands as a new bank, whole or not at all
Four collisions answered explicitly: ids reminted, names never overwritten, content deduped before the write, bank name auto-suffixed. Degraded ledger refuses before the picker.
This commit is contained in:
@@ -117,6 +117,17 @@ bool BankBook::createBank(const std::string& id, const std::string& displayName)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Runs behind displayNameTaken so the probe and the create/rename check can never
|
||||
// disagree about what "already used" means. exceptId is deliberately "" — no bank can
|
||||
// carry an empty id, so nothing is excluded from the scan.
|
||||
std::string BankBook::uniqueDisplayName(const std::string& seed) const {
|
||||
if (!displayNameTaken(seed, /*exceptId=*/std::string{})) return seed;
|
||||
for (int n = 2;; ++n) {
|
||||
std::string candidate = seed + " " + std::to_string(n);
|
||||
if (!displayNameTaken(candidate, /*exceptId=*/std::string{})) return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
bool BankBook::renameBank(const std::string& id, const std::string& displayName) {
|
||||
if (id == kPoolBankId) return false; // pool is un-renamable
|
||||
Bank* b = bank(id);
|
||||
|
||||
@@ -100,6 +100,17 @@ public:
|
||||
// no-op success.
|
||||
bool renameBank(const std::string& id, const std::string& displayName);
|
||||
|
||||
// The first name in the sequence `seed`, "seed 2", "seed 3", … whose fold is free
|
||||
// in this book — what a caller that must not be rejected (the package import) asks
|
||||
// for before createBank. First-FREE-ascending, not highest-plus-one, so it fills a
|
||||
// gap ("Drums" + "Drums 3" present yields "Drums 2") and is a pure function of the
|
||||
// current name set. The seed is returned verbatim when free and is NEVER re-parsed:
|
||||
// a bare trailing integer cannot be told from a user's own name, so "Kit 808" would
|
||||
// become "Kit 2" under a stripping rule. Terminates by pigeonhole (one of the first
|
||||
// N+1 candidates is free for N banks), so it needs no cap. A blank seed comes back
|
||||
// blank — what a missing name should become is the caller's policy, not the model's.
|
||||
std::string uniqueDisplayName(const std::string& seed) const;
|
||||
|
||||
// Deletes a named bank and its member entries (files untouched — a shell/prune
|
||||
// concern). Rejects (false, no mutation) an unknown id or the pool. Remaining
|
||||
// ordinals compact after; if the deleted bank was active, falls back to the pool.
|
||||
|
||||
Reference in New Issue
Block a user