1const std = @import("../std.zig"); 2const mem = std.mem; 3const fs = std.fs; 4const File = std.fs.File; 5 6pub const BufferedAtomicFile = struct { 7 atomic_file: fs.AtomicFile, 8 file_writer: File.Writer, 9 buffered_writer: BufferedWriter, 10 allocator: mem.Allocator, 11 12 pub const buffer_size = 4096; 13 pub const BufferedWriter = std.io.BufferedWriter(buffer_size, File.Writer); 14 pub const Writer = std.io.Writer(*BufferedWriter, BufferedWriter.Error, BufferedWriter.write); 15 16 /// TODO when https://github.com/ziglang/zig/issues/2761 is solved 17 /// this API will not need an allocator 18 pub fn create( 19 allocator: mem.Allocator, 20 dir: fs.Dir, 21 dest_path: []const u8, 22 atomic_file_options: fs.Dir.AtomicFileOptions, 23 ) !*BufferedAtomicFile { 24 var self = try allocator.create(BufferedAtomicFile); 25 self.* = BufferedAtomicFile{ 26 .atomic_file = undefined, 27 .file_writer = undefined, 28 .buffered_writer = undefined, 29 .allocator = allocator, 30 }; 31 errdefer allocator.destroy(self); 32 33 self.atomic_file = try dir.atomicFile(dest_path, atomic_file_options); 34 errdefer self.atomic_file.deinit(); 35 36 self.file_writer = self.atomic_file.file.writer(); 37 self.buffered_writer = .{ .unbuffered_writer = self.file_writer }; 38 return self; 39 } 40 41 /// always call destroy, even after successful finish() 42 pub fn destroy(self: *BufferedAtomicFile) void { 43 self.atomic_file.deinit(); 44 self.allocator.destroy(self); 45 } 46 47 pub fn finish(self: *BufferedAtomicFile) !void { 48 try self.buffered_writer.flush(); 49 try self.atomic_file.finish(); 50 } 51 52 pub fn writer(self: *BufferedAtomicFile) Writer { 53 return .{ .context = &self.buffered_writer }; 54 } 55}; 56