diff options
Diffstat (limited to 'src/fs.zig')
| -rw-r--r-- | src/fs.zig | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/fs.zig b/src/fs.zig index 2a141d1..eb8c3e0 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -35,33 +35,50 @@ pub const FileSwapper = struct { }; } + pub fn file(self: FileSwapper) std.fs.File { + return self.tmp; + } + pub fn writer(self: FileSwapper) std.fs.File.Writer { return self.tmp.writer(); } - pub fn close(self: FileSwapper) void { - defer self.allocator.free(self.tmp_path); - defer self.tmp.close(); - - // flush writes - self.tmp.sync() catch - @panic("sync tmp file"); - - // check if target path exists + fn target_exists(self: FileSwapper) !bool { var found = true; std.fs.cwd().access(self.target_path, .{}) catch |e| switch (e) { error.FileNotFound => found = false, - else => @panic("unable to stat target path"), + else => |err| return err, }; + return found; + } + + pub fn swap(self: FileSwapper) !void { + std.log.debug("swapping {s} -> {s}", .{ self.tmp_path, self.target_path }); + + // flush writes + self.tmp.sync() catch + @panic("sync tmp file"); // swap file into final location - std.fs.rename( + // NOTE: the tmp fd is still valid after this + try std.fs.rename( std.fs.cwd(), self.tmp_path, std.fs.cwd(), self.target_path, - ) catch - @panic("rename tmp file"); + ); + } + + pub fn close(self: FileSwapper) void { + var found = true; + std.fs.cwd().access(self.tmp_path, .{}) catch |e| switch (e) { + error.FileNotFound => found = false, + else => @panic("access tmp path"), + }; + if (found) self.swap() catch @panic("failed to swap target file"); + + self.allocator.free(self.tmp_path); + self.tmp.close(); } }; |