mirror of
https://github.com/NixOS/nix
synced 2025-07-06 09:11:47 +02:00
Improve the FileSystemObjectSink
interface
More invariants are enforced in the type, and less state needs to be stored in the main sink itself. The method here is roughly that known as "session types". Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
parent
966d6fcd01
commit
6365bbfa81
9 changed files with 357 additions and 219 deletions
|
@ -134,36 +134,43 @@ void MemorySink::createDirectory(const Path & path)
|
|||
throw Error("file '%s' is not a directory", path);
|
||||
};
|
||||
|
||||
void MemorySink::createRegularFile(const Path & path)
|
||||
struct CreateMemoryRegularFile : CreateRegularFileSink {
|
||||
File::Regular & regularFile;
|
||||
|
||||
CreateMemoryRegularFile(File::Regular & r)
|
||||
: regularFile(r)
|
||||
{ }
|
||||
|
||||
void operator () (std::string_view data) override;
|
||||
void isExecutable() override;
|
||||
void preallocateContents(uint64_t size) override;
|
||||
};
|
||||
|
||||
void MemorySink::createRegularFile(const Path & path, std::function<void(CreateRegularFileSink &)> func)
|
||||
{
|
||||
auto * f = dst.open(CanonPath{path}, File { File::Regular {} });
|
||||
if (!f)
|
||||
throw Error("file '%s' cannot be made because some parent file is not a directory", path);
|
||||
if (!(r = std::get_if<File::Regular>(&f->raw)))
|
||||
if (auto * rp = std::get_if<File::Regular>(&f->raw)) {
|
||||
CreateMemoryRegularFile crf { *rp };
|
||||
func(crf);
|
||||
} else
|
||||
throw Error("file '%s' is not a regular file", path);
|
||||
}
|
||||
|
||||
void MemorySink::closeRegularFile()
|
||||
void CreateMemoryRegularFile::isExecutable()
|
||||
{
|
||||
r = nullptr;
|
||||
regularFile.executable = true;
|
||||
}
|
||||
|
||||
void MemorySink::isExecutable()
|
||||
void CreateMemoryRegularFile::preallocateContents(uint64_t len)
|
||||
{
|
||||
assert(r);
|
||||
r->executable = true;
|
||||
regularFile.contents.reserve(len);
|
||||
}
|
||||
|
||||
void MemorySink::preallocateContents(uint64_t len)
|
||||
void CreateMemoryRegularFile::operator () (std::string_view data)
|
||||
{
|
||||
assert(r);
|
||||
r->contents.reserve(len);
|
||||
}
|
||||
|
||||
void MemorySink::receiveContents(std::string_view data)
|
||||
{
|
||||
assert(r);
|
||||
r->contents += data;
|
||||
regularFile.contents += data;
|
||||
}
|
||||
|
||||
void MemorySink::createSymlink(const Path & path, const std::string & target)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue