| ... | ... | @@ -21,6 +21,50 @@ const testing = std.testing; |
| 21 | 21 | |
| 22 | 22 | pub const output = @import("tar/output.zig"); |
| 23 | 23 | |
| 24 | /// Provide this to receive detailed error messages. |
| 25 | /// When this is provided, some errors which would otherwise be returned |
| 26 | /// immediately will instead be added to this structure. The API user must check |
| 27 | /// the errors in diagnostics to know whether the operation succeeded or failed. |
| 28 | pub const Diagnostics = struct { |
| 29 | allocator: std.mem.Allocator, |
| 30 | errors: std.ArrayListUnmanaged(Error) = .{}, |
| 31 | |
| 32 | pub const Error = union(enum) { |
| 33 | unable_to_create_sym_link: struct { |
| 34 | code: anyerror, |
| 35 | file_name: []const u8, |
| 36 | link_name: []const u8, |
| 37 | }, |
| 38 | unable_to_create_file: struct { |
| 39 | code: anyerror, |
| 40 | file_name: []const u8, |
| 41 | }, |
| 42 | unsupported_file_type: struct { |
| 43 | file_name: []const u8, |
| 44 | file_type: Header.Kind, |
| 45 | }, |
| 46 | }; |
| 47 | |
| 48 | pub fn deinit(d: *Diagnostics) void { |
| 49 | for (d.errors.items) |item| { |
| 50 | switch (item) { |
| 51 | .unable_to_create_sym_link => |info| { |
| 52 | d.allocator.free(info.file_name); |
| 53 | d.allocator.free(info.link_name); |
| 54 | }, |
| 55 | .unable_to_create_file => |info| { |
| 56 | d.allocator.free(info.file_name); |
| 57 | }, |
| 58 | .unsupported_file_type => |info| { |
| 59 | d.allocator.free(info.file_name); |
| 60 | }, |
| 61 | } |
| 62 | } |
| 63 | d.errors.deinit(d.allocator); |
| 64 | d.* = undefined; |
| 65 | } |
| 66 | }; |
| 67 | |
| 24 | 68 | /// pipeToFileSystem options |
| 25 | 69 | pub const PipeOptions = struct { |
| 26 | 70 | /// Number of directory levels to skip when extracting files. |
| ... | ... | @@ -29,10 +73,7 @@ pub const PipeOptions = struct { |
| 29 | 73 | mode_mode: ModeMode = .executable_bit_only, |
| 30 | 74 | /// Prevents creation of empty directories. |
| 31 | 75 | exclude_empty_directories: bool = false, |
| 32 | | /// Provide this to receive detailed error messages. |
| 33 | | /// When this is provided, some errors which would otherwise be returned immediately |
| 34 | | /// will instead be added to this structure. The API user must check the errors |
| 35 | | /// in diagnostics to know whether the operation succeeded or failed. |
| 76 | /// Collects error messages during unpacking |
| 36 | 77 | diagnostics: ?*Diagnostics = null, |
| 37 | 78 | |
| 38 | 79 | pub const ModeMode = enum { |
| ... | ... | @@ -44,46 +85,6 @@ pub const PipeOptions = struct { |
| 44 | 85 | /// Other bits of the mode are left as the default when creating files. |
| 45 | 86 | executable_bit_only, |
| 46 | 87 | }; |
| 47 | | |
| 48 | | pub const Diagnostics = struct { |
| 49 | | allocator: std.mem.Allocator, |
| 50 | | errors: std.ArrayListUnmanaged(Error) = .{}, |
| 51 | | |
| 52 | | pub const Error = union(enum) { |
| 53 | | unable_to_create_sym_link: struct { |
| 54 | | code: anyerror, |
| 55 | | file_name: []const u8, |
| 56 | | link_name: []const u8, |
| 57 | | }, |
| 58 | | unable_to_create_file: struct { |
| 59 | | code: anyerror, |
| 60 | | file_name: []const u8, |
| 61 | | }, |
| 62 | | unsupported_file_type: struct { |
| 63 | | file_name: []const u8, |
| 64 | | file_type: Header.Kind, |
| 65 | | }, |
| 66 | | }; |
| 67 | | |
| 68 | | pub fn deinit(d: *Diagnostics) void { |
| 69 | | for (d.errors.items) |item| { |
| 70 | | switch (item) { |
| 71 | | .unable_to_create_sym_link => |info| { |
| 72 | | d.allocator.free(info.file_name); |
| 73 | | d.allocator.free(info.link_name); |
| 74 | | }, |
| 75 | | .unable_to_create_file => |info| { |
| 76 | | d.allocator.free(info.file_name); |
| 77 | | }, |
| 78 | | .unsupported_file_type => |info| { |
| 79 | | d.allocator.free(info.file_name); |
| 80 | | }, |
| 81 | | } |
| 82 | | } |
| 83 | | d.errors.deinit(d.allocator); |
| 84 | | d.* = undefined; |
| 85 | | } |
| 86 | | }; |
| 87 | 88 | }; |
| 88 | 89 | |
| 89 | 90 | const Header = struct { |
| ... | ... | @@ -246,13 +247,8 @@ pub const IteratorOptions = struct { |
| 246 | 247 | file_name_buffer: []u8, |
| 247 | 248 | /// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities. |
| 248 | 249 | link_name_buffer: []u8, |
| 249 | | /// Provide this to receive detailed error messages. |
| 250 | | /// When this is provided, some errors which would otherwise be returned immediately |
| 251 | | /// will instead be added to this structure. The API user must check the errors |
| 252 | | /// in diagnostics to know whether the operation succeeded or failed. |
| 250 | /// Collects error messages during unpacking |
| 253 | 251 | diagnostics: ?*Diagnostics = null, |
| 254 | | |
| 255 | | pub const Diagnostics = PipeOptions.Diagnostics; |
| 256 | 252 | }; |
| 257 | 253 | |
| 258 | 254 | /// Iterates over files in tar archive. |
| ... | ... | @@ -277,7 +273,7 @@ pub const FileKind = enum { |
| 277 | 273 | pub fn Iterator(comptime ReaderType: type) type { |
| 278 | 274 | return struct { |
| 279 | 275 | reader: ReaderType, |
| 280 | | diagnostics: ?*PipeOptions.Diagnostics = null, |
| 276 | diagnostics: ?*Diagnostics = null, |
| 281 | 277 | |
| 282 | 278 | // buffers for heeader and file attributes |
| 283 | 279 | header_buffer: [Header.SIZE]u8 = undefined, |