-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathutils.zig
85 lines (77 loc) · 2.59 KB
/
utils.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
const std = @import("std");
const c = @import("c_api.zig");
pub fn fromCStructsToArrayList(from_array: anytype, from_array_length: i32, comptime ToType: type, allocator: std.mem.Allocator) !std.ArrayList(ToType) {
const len = @as(usize, @intCast(from_array_length));
var arr = try std.ArrayList(ToType).initCapacity(allocator, len);
{
var i: usize = 0;
while (i < len) : (i += 1) {
const elem = blk: {
const elem = ToType.initFromC(from_array[i]);
break :blk switch (comptime @typeInfo(@TypeOf(elem))) {
.ErrorUnion => try elem,
else => elem,
};
};
try arr.append(elem);
}
}
return arr;
}
// note: cannot implicitly cast double pointer '[*c]?*anyopaque' to anyopaque pointer '?*anyopaque'
pub fn ensurePtrNotNull(ptr: anytype) !@TypeOf(ptr) {
if (ptr == null) return error.AllocationError;
return ptr.?;
}
pub fn ensureFileExists(path: []const u8, allow_zero_byte: bool) !void {
const stat = std.fs.cwd().statFile(path) catch |err| switch (err) {
error.FileNotFound => {
std.debug.print("File not found: {s}\n", .{path});
return error.FileNotFound;
},
else => return err,
};
if (stat.size == 0 and !allow_zero_byte) {
std.debug.print("File is empty: {s}\n", .{path});
return error.FileEmpty;
}
}
pub fn downloadFile(url: []const u8, dir: []const u8, allocator: std.mem.Allocator) !void {
if (dir[dir.len - 1] != '/') unreachable;
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
const arena_allocator = arena.allocator();
var split_url = std.mem.split(u8, url, "/");
var filename: []const u8 = undefined;
while (split_url.next()) |s| {
filename = s;
}
const dir_filename = try std.fmt.allocPrint(
arena_allocator,
"{s}{s}",
.{ dir, filename },
);
var child = std.ChildProcess.init(
&.{
"curl",
url,
"-Lo",
dir_filename,
"--create-dirs",
},
arena_allocator,
);
child.stderr = std.io.getStdErr();
child.stdout = std.io.getStdOut();
ensureFileExists(dir_filename, false) catch |err| switch (err) {
error.FileNotFound, error.FileEmpty => {
_ = try child.spawnAndWait();
return;
},
else => return err,
};
}
test "ensureNotNull" {
var ptr: ?*u8 = null;
try std.testing.expectError(error.AllocationError, ensurePtrNotNull(ptr));
}