Files
NXST/ISSUES/phase6-cleanup.md
T
DragonSpirit 6f8ede035f refactor: phase 6 cleanup — RAII handles and io::restore split
- AccountProfileHandle RAII wrapper in handles.hpp; applied in
  account.cpp (getUser, iconPath) replacing manual accountProfileClose
- FILE* in iconPath replaced with existing FileHandle RAII wrapper
- io::restore split into clearSaveRoot + extractAndCommit static helpers;
  public signature unchanged
- sendAll/recvAll kept as bool — callers don't propagate the error string,
  Result<void> would add noise without benefit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 14:56:38 +03:00

3.2 KiB

Phase 6 cleanup — unfinished items

Leftover from the architectural refactor. All items are small, contained, and build on the already-present Result<T> + RAII infrastructure.

Status

# Item File(s) Status
1 AccountProfileHandle RAII + apply in account.cpp handles.hpp, account.cpp [x]
2 FILE* in account.cpp::iconPathFileHandle account.cpp [x]
3 Split io::restore into three focused functions io.cpp, io.hpp [x]
4 sendAll/recvAllnxst::Result<void> transfer_service.cpp dropped — callers don't propagate error, bool is correct

Item 1 — AccountProfileHandle RAII

File: include/nxst/infra/fs/handles.hpp

Add after FileHandle:

// RAII wrapper for AccountProfile — auto-closes on destruction.
struct AccountProfileHandle {
    AccountProfile profile{};
    bool valid{false};

    AccountProfileHandle() = default;
    ~AccountProfileHandle() {
        if (valid)
            accountProfileClose(&profile);
    }
    AccountProfileHandle(const AccountProfileHandle&) = delete;
    AccountProfileHandle& operator=(const AccountProfileHandle&) = delete;

    AccountProfile* get() { return &profile; }
};

Apply in account.cpp:

getUser() (line ~62): replace raw AccountProfile profile + manual accountProfileClose with AccountProfileHandle.

iconPath() (line ~98): same — wrap AccountProfile profileAccountProfileHandle.


Item 2 — FILE* in iconPathFileHandle

File: src/domain/account.cpp, lines ~115-119

// before
FILE* f = fopen(path, "wb");
if (!f) return "";
fwrite(buf.data(), 1, outSize, f);
fclose(f);

// after
nxst::FileHandle f(fopen(path, "wb"));
if (!f) return "";
fwrite(buf.data(), 1, outSize, f.get());

No fclose needed — FileHandle dtor handles it.


Item 3 — Split io::restore

Current: io.cpp:236-317 — one 80-line function doing mount, validate, clear, copy, commit.

Split into three static helpers in io.cpp (not exposed in header):

static nxst::Result<void> clearSaveRoot(const std::string& dst_path)
    — removes all files/dirs under save:/

static nxst::Result<void> extractAndCommit(const std::string& src_path, const std::string& dst_path)
    — copyDirectory + fsdevCommitDevice

io::restore (public)
    — mount, validate src, call clearSaveRoot, call extractAndCommit, return success

io.hpp declaration unchanged — io::restore signature stays the same.


Item 4 — sendAll/recvAllnxst::Result<void>

File: src/service/transfer_service.cpp, lines 32-55

// before
static bool sendAll(int sock, const void* buf, size_t len) { ... return true/false; }
static bool recvAll(int sock, void* buf, size_t len)       { ... return true/false; }

// after
static nxst::Result<void> sendAll(int sock, const void* buf, size_t len);
static nxst::Result<void> recvAll(int sock, void* buf, size_t len);

All callers: if (!sendAll(...))if (!sendAll(...).isOk()).


Verification

cmake --build build/   # must produce NXST.elf + NXST.nro with zero warnings

No observable behavior change — pure refactor.