package: one bank leaves the project as one .rsbank, or the export refuses and says why
Pure planner classifies missing/unreadable/unrepresentable and repairs transport names; the verb digests, streams and commits atomically over a const session.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
// shell/package/export_bank — the promptless bank-export verb: survey, digest,
|
||||
// stream, commit. No prompts and no message boxes (shell/actions/
|
||||
// package_export_action is the skin). The session arrives CONST, which is how "an
|
||||
// export writes no ext state, opens no undo point and never bumps the bank
|
||||
// generation" is enforced rather than remembered — every mutator on the session is
|
||||
// non-const. Blocking I/O: UI-thread actions only.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "core/package/bank_package.h"
|
||||
#include "core/package/export_plan.h"
|
||||
|
||||
namespace reasampler {
|
||||
|
||||
class ReaSamplerSession;
|
||||
|
||||
struct ExportRequest {
|
||||
std::string projectDir; // absolute; the root the index's relative paths hang off
|
||||
std::string bankId;
|
||||
std::string destAbsPath; // the .rsbank to write
|
||||
std::int64_t exportTimestamp = 0; // manifest envelope; the caller's clock read
|
||||
// Both default false and are set ONLY after the skin's explicit confirm: one
|
||||
// lists what is absent, the other names the destination being replaced.
|
||||
bool allowIncomplete = false;
|
||||
bool allowOverwrite = false;
|
||||
};
|
||||
|
||||
enum class ExportStatus {
|
||||
Written,
|
||||
NoSuchBank,
|
||||
NoProjectDir,
|
||||
RefusedIncomplete,
|
||||
RefusedUnrepresentable,
|
||||
RefusedDestinationExists,
|
||||
SourceReadFailed, // a file the plan classified Present would not read, or is empty
|
||||
SourceChanged, // a payload's bytes moved between the digest pass and the stream pass
|
||||
EncodeFailed,
|
||||
WriteFailed,
|
||||
};
|
||||
|
||||
struct ExportOutcome {
|
||||
ExportStatus status = ExportStatus::WriteFailed;
|
||||
std::size_t entriesWritten = 0;
|
||||
std::uint64_t bytesWritten = 0;
|
||||
std::string bankDisplayName;
|
||||
std::vector<package::ExcludedEntry> excluded;
|
||||
std::string offendingName; // the entry a SourceReadFailed / SourceChanged names
|
||||
};
|
||||
|
||||
struct ExportSurvey {
|
||||
bool bankFound = false;
|
||||
package::ExportPlan plan;
|
||||
};
|
||||
|
||||
// Report-before-acting: the same plan exportBank recomputes, with nothing written.
|
||||
// Read-only against both the project and the filesystem.
|
||||
ExportSurvey surveyBankExport(const ReaSamplerSession& session,
|
||||
const std::string& projectDir,
|
||||
const std::string& bankId);
|
||||
|
||||
// Fills each manifest entry's byteLength and byteHash from its source file — the
|
||||
// digest pass, one payload in memory at a time. False with `outFailedName` set when a
|
||||
// source will not read or is empty; a zero-length entry cannot round-trip the
|
||||
// format's own seam, so it is a failure here rather than an entry.
|
||||
bool digestSources(package::PackageManifest& manifest,
|
||||
const std::vector<std::string>& sourceAbsPaths,
|
||||
std::string& outFailedName);
|
||||
|
||||
// Streams one package to `destAbsPath`: the encoded prefix, then each payload re-read
|
||||
// from `sourceAbsPaths` (parallel to `manifest.entries`) and re-checked against the
|
||||
// length and digest recorded for it before it is appended — so the digest the
|
||||
// manifest claims describes the bytes actually written, not the bytes a concurrent
|
||||
// edit replaced. Any failure abandons the writer, leaving the destination absent or
|
||||
// holding its prior contents.
|
||||
//
|
||||
// Public because that atomicity is this function's property: proving it needs a
|
||||
// failure injected mid-stream, which is a call to this seam, not to exportBank.
|
||||
ExportOutcome writePackageFile(const package::EncodedPackage& encoded,
|
||||
const package::PackageManifest& manifest,
|
||||
const std::vector<std::string>& sourceAbsPaths,
|
||||
const std::string& destAbsPath);
|
||||
|
||||
// The verb: plan, gate on the verdict and the destination, digest, encode, stream.
|
||||
ExportOutcome exportBank(const ReaSamplerSession& session, const ExportRequest& req);
|
||||
|
||||
} // namespace reasampler
|
||||
Reference in New Issue
Block a user