| ... | @@ -21,6 +21,50 @@ const testing = std.testing; | ... | @@ -21,6 +21,50 @@ const testing = std.testing; |
| 21 | | 21 | |
| 22 | pub const output = @import("tar/output.zig"); | 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 | /// pipeToFileSystem options | 68 | /// pipeToFileSystem options |
| 25 | pub const PipeOptions = struct { | 69 | pub const PipeOptions = struct { |
| 26 | /// Number of directory levels to skip when extracting files. | 70 | /// Number of directory levels to skip when extracting files. |
| ... | @@ -29,10 +73,7 @@ pub const PipeOptions = struct { | ... | @@ -29,10 +73,7 @@ pub const PipeOptions = struct { |
| 29 | mode_mode: ModeMode = .executable_bit_only, | 73 | mode_mode: ModeMode = .executable_bit_only, |
| 30 | /// Prevents creation of empty directories. | 74 | /// Prevents creation of empty directories. |
| 31 | exclude_empty_directories: bool = false, | 75 | exclude_empty_directories: bool = false, |
| 32 | /// Provide this to receive detailed error messages. | 76 | /// Collects error messages during unpacking |
| 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. | | |
| 36 | diagnostics: ?*Diagnostics = null, | 77 | diagnostics: ?*Diagnostics = null, |
| 37 | | 78 | |
| 38 | pub const ModeMode = enum { | 79 | pub const ModeMode = enum { |
| ... | @@ -44,46 +85,6 @@ pub const PipeOptions = struct { | ... | @@ -44,46 +85,6 @@ pub const PipeOptions = struct { |
| 44 | /// Other bits of the mode are left as the default when creating files. | 85 | /// Other bits of the mode are left as the default when creating files. |
| 45 | executable_bit_only, | 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 | const Header = struct { | 90 | const Header = struct { |
| ... | @@ -246,13 +247,8 @@ pub const IteratorOptions = struct { | ... | @@ -246,13 +247,8 @@ pub const IteratorOptions = struct { |
| 246 | file_name_buffer: []u8, | 247 | file_name_buffer: []u8, |
| 247 | /// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities. | 248 | /// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities. |
| 248 | link_name_buffer: []u8, | 249 | link_name_buffer: []u8, |
| 249 | /// Provide this to receive detailed error messages. | 250 | /// Collects error messages during unpacking |
| 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. | | |
| 253 | diagnostics: ?*Diagnostics = null, | 251 | diagnostics: ?*Diagnostics = null, |
| 254 | | | |
| 255 | pub const Diagnostics = PipeOptions.Diagnostics; | | |
| 256 | }; | 252 | }; |
| 257 | | 253 | |
| 258 | /// Iterates over files in tar archive. | 254 | /// Iterates over files in tar archive. |
| ... | @@ -277,7 +273,7 @@ pub const FileKind = enum { | ... | @@ -277,7 +273,7 @@ pub const FileKind = enum { |
| 277 | pub fn Iterator(comptime ReaderType: type) type { | 273 | pub fn Iterator(comptime ReaderType: type) type { |
| 278 | return struct { | 274 | return struct { |
| 279 | reader: ReaderType, | 275 | reader: ReaderType, |
| 280 | diagnostics: ?*PipeOptions.Diagnostics = null, | 276 | diagnostics: ?*Diagnostics = null, |
| 281 | | 277 | |
| 282 | // buffers for heeader and file attributes | 278 | // buffers for heeader and file attributes |
| 283 | header_buffer: [Header.SIZE]u8 = undefined, | 279 | header_buffer: [Header.SIZE]u8 = undefined, |