/* * This source code is released into the public domain. */ module; #include #include #include #include #include #include #include #include export module nihil:write_file; import :error; import :guard; import :monad; import :open_file; import :rename_file; namespace nihil { /* * Write the contents of a range to a file. Returns the number of bytes * written. */ export [[nodiscard]] auto write_file(std::filesystem::path const &filename, std::ranges::contiguous_range auto &&range, int mode = 0777) -> std::expected { auto file = co_await open_file(filename, O_CREAT|O_WRONLY, mode); auto nbytes = co_await write(file, range); co_return nbytes; } /* * Utility wrapper for non-contiguous ranges. */ export [[nodiscard]] auto write_file(std::filesystem::path const &filename, std::ranges::range auto &&range) -> std::expected requires(!std::ranges::contiguous_range) { return write_file(filename, std::vector(std::from_range, range)); } /* * Write the contents of a range to a file safely. The data will be written * to ".tmp", and if the write succeeds, the temporary file will be * renamed to the target filename. If an error occurs, the target file will * not be modified. */ export [[nodiscard]] auto safe_write_file(std::filesystem::path const &filename, std::ranges::range auto &&range) -> std::expected { auto tmpfile = filename; tmpfile.remove_filename(); tmpfile /= (filename.filename().native() + ".tmp"); auto tmpfile_guard = guard([&tmpfile] { ::unlink(tmpfile.c_str()); }); co_await write_file(tmpfile, range); co_await rename_file(tmpfile, filename); tmpfile_guard.release(); co_return {}; } } // namespace nihil