1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-16 15:32:43 +01:00
nix/src/libutil/include/nix/fs-sink.hh
John Ericson f3e1c47f47 Separate headers from source files
The short answer for why we need to do this is so we can consistently do
`#include "nix/..."`. Without this change, there are ways to still make
that work, but they are hacky, and they have downsides such as making it
harder to make sure headers from the wrong Nix library (e..g.
`libnixexpr` headers in `libnixutil`) aren't being used.

The C API alraedy used `nix_api_*`, so its headers are *not* put in
subdirectories accordingly.

Progress on #7876

We resisted doing this for a while because it would be annoying to not
have the header source file pairs close by / easy to change file
path/name from one to the other. But I am ameliorating that with
symlinks in the next commit.
2025-03-31 12:20:25 -04:00

123 lines
3.1 KiB
C++

#pragma once
///@file
#include "nix/serialise.hh"
#include "nix/source-accessor.hh"
#include "nix/file-system.hh"
namespace nix {
/**
* Actions on an open regular file in the process of creating it.
*
* See `FileSystemObjectSink::createRegularFile`.
*/
struct CreateRegularFileSink : Sink
{
virtual void isExecutable() = 0;
/**
* An optimization. By default, do nothing.
*/
virtual void preallocateContents(uint64_t size) { };
};
struct FileSystemObjectSink
{
virtual ~FileSystemObjectSink() = default;
virtual void createDirectory(const CanonPath & path) = 0;
/**
* This function in general is no re-entrant. Only one file can be
* written at a time.
*/
virtual void createRegularFile(
const CanonPath & path,
std::function<void(CreateRegularFileSink &)>) = 0;
virtual void createSymlink(const CanonPath & path, const std::string & target) = 0;
};
/**
* An extension of `FileSystemObjectSink` that supports file types
* that are not supported by Nix's FSO model.
*/
struct ExtendedFileSystemObjectSink : virtual FileSystemObjectSink
{
/**
* Create a hard link. The target must be the path of a previously
* encountered file relative to the root of the FSO.
*/
virtual void createHardlink(const CanonPath & path, const CanonPath & target) = 0;
};
/**
* Recursively copy file system objects from the source into the sink.
*/
void copyRecursive(
SourceAccessor & accessor, const CanonPath & sourcePath,
FileSystemObjectSink & sink, const CanonPath & destPath);
/**
* Ignore everything and do nothing
*/
struct NullFileSystemObjectSink : FileSystemObjectSink
{
void createDirectory(const CanonPath & path) override { }
void createSymlink(const CanonPath & path, const std::string & target) override { }
void createRegularFile(
const CanonPath & path,
std::function<void(CreateRegularFileSink &)>) override;
};
/**
* Write files at the given path
*/
struct RestoreSink : FileSystemObjectSink
{
std::filesystem::path dstPath;
bool startFsync = false;
explicit RestoreSink(bool startFsync)
: startFsync{startFsync}
{ }
void createDirectory(const CanonPath & path) override;
void createRegularFile(
const CanonPath & path,
std::function<void(CreateRegularFileSink &)>) override;
void createSymlink(const CanonPath & path, const std::string & target) override;
};
/**
* Restore a single file at the top level, passing along
* `receiveContents` to the underlying `Sink`. For anything but a single
* file, set `regular = true` so the caller can fail accordingly.
*/
struct RegularFileSink : FileSystemObjectSink
{
bool regular = true;
Sink & sink;
RegularFileSink(Sink & sink) : sink(sink) { }
void createDirectory(const CanonPath & path) override
{
regular = false;
}
void createSymlink(const CanonPath & path, const std::string & target) override
{
regular = false;
}
void createRegularFile(
const CanonPath & path,
std::function<void(CreateRegularFileSink &)>) override;
};
}