From 93647298737946f30f7e16a9ddcc25c460cbf265 Mon Sep 17 00:00:00 2001 From: oupson Date: Sat, 20 Aug 2022 10:16:13 +0200 Subject: [PATCH] Add a result type to get requests --- src/app.zig | 78 +++++++++++++++++++++++++++++++--------------------- src/curl.zig | 33 +++++++++++++++++----- 2 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/app.zig b/src/app.zig index 679e7ef..cf12bf9 100644 --- a/src/app.zig +++ b/src/app.zig @@ -238,7 +238,7 @@ fn updateAlert( try request.append(0); - var streams: twitch.TwitchRes([]const twitch.Stream) = try client.getJSON( + var result: curl.Result(twitch.TwitchRes([]const twitch.Stream)) = try client.getJSON( twitch.TwitchRes([]const twitch.Stream), @ptrCast([*:0]const u8, request.items), headers, @@ -246,29 +246,37 @@ fn updateAlert( request.deinit(); - if (streams.data.len > 0) { - var embeds = std.ArrayList(webhook.Embed).init(allocator); + switch (result) { + .ok => |*streams| { + if (streams.data.len > 0) { + var embeds = std.ArrayList(webhook.Embed).init(allocator); - for (streams.data) |s| { - if (try appendEmbed(allocator, &s, database)) |e| { - std.log.debug("sending {s}", .{s.title}); - try embeds.append(e); + for (streams.data) |s| { + if (try appendEmbed(allocator, &s, database)) |e| { + std.log.debug("sending {s}", .{s.title}); + try embeds.append(e); + } + } + + if (embeds.items.len > 0) { + var res = try client.postJSON(config.webhook_url, webhook.Webhook{ + .username = "Twitch", + .content = "Live alert", + .embeds = embeds.items, + }, null); + + client.allocator.free(res); + } + embeds.deinit(); } - } - if (embeds.items.len > 0) { - var res = try client.postJSON(config.webhook_url, webhook.Webhook{ - .username = "Twitch", - .content = "Live alert", - .embeds = embeds.items, - }, null); - - client.allocator.free(res); - } - embeds.deinit(); + streams.deinit(allocator); + }, + .errorCode => |errorCode| { + std.log.err("Failed to get streams : error code {}\n", .{errorCode}); + return error.CurlFailed; + }, } - - streams.deinit(allocator); } fn appendEmbed(allocator: std.mem.Allocator, stream: *const twitch.Stream, db: *sqlite.Database) anyerror!?webhook.Embed { @@ -442,22 +450,30 @@ fn insertOrReplaceStreamers( try request.append(0); - var streamers: twitch.TwitchRes([]const twitch.User) = try client.getJSON( + var result: curl.Result(twitch.TwitchRes([]const twitch.User)) = try client.getJSON( twitch.TwitchRes([]const twitch.User), @ptrCast([*:0]const u8, request.items), headers, ); - for (streamers.data) |streamer| { - var stm = try db.prepare("INSERT OR REPLACE INTO STREAMER(idStreamer, loginStreamer, nameStreamer, imageUrlStreamer) VALUES(?, ?, ?, ?)"); - try stm.bind(1, sqlite.U8Array.text(streamer.id)); - try stm.bind(2, sqlite.U8Array.text(streamer.login)); - try stm.bind(3, sqlite.U8Array.text(streamer.display_name)); - try stm.bind(4, sqlite.U8Array.text(streamer.profile_image_url)); + switch (result) { + .ok => |*streamers| { + for (streamers.data) |streamer| { + var stm = try db.prepare("INSERT OR REPLACE INTO STREAMER(idStreamer, loginStreamer, nameStreamer, imageUrlStreamer) VALUES(?, ?, ?, ?)"); + try stm.bind(1, sqlite.U8Array.text(streamer.id)); + try stm.bind(2, sqlite.U8Array.text(streamer.login)); + try stm.bind(3, sqlite.U8Array.text(streamer.display_name)); + try stm.bind(4, sqlite.U8Array.text(streamer.profile_image_url)); - try stm.exec(); - stm.finalize(); + try stm.exec(); + stm.finalize(); + } + + streamers.deinit(allocator); + }, + .errorCode => |errorCode| { + std.log.err("Failed to get streamers : error code {}\n", .{errorCode}); + return error.CurlFailed; + }, } - - streamers.deinit(allocator); } diff --git a/src/curl.zig b/src/curl.zig index e59dd17..674bb9c 100644 --- a/src/curl.zig +++ b/src/curl.zig @@ -12,6 +12,15 @@ const ArrayListReader = struct { position: usize, }; +const ResultTag = enum { ok, errorCode }; + +pub fn Result(comptime T: type) type { + return union(ResultTag) { + ok: T, + errorCode: c_long, + }; +} + pub const Client = struct { ptr: *cURL.CURL, allocator: mem.Allocator, @@ -57,7 +66,7 @@ pub const Client = struct { return error.CURLPerformFailed; } - pub fn getJSON(self: *@This(), comptime T: type, url: [*:0]const u8, headers: ?*std.StringHashMap([]const u8)) anyerror!T { + pub fn getJSON(self: *@This(), comptime T: type, url: [*:0]const u8, headers: ?*std.StringHashMap([]const u8)) anyerror!Result(T) { var response_buffer = std.ArrayList(u8).init(self.allocator); if (cURL.curl_easy_setopt(self.ptr, cURL.CURLOPT_URL, url) != cURL.CURLE_OK) return error.CURLPerformFailed; @@ -92,17 +101,27 @@ pub const Client = struct { if (cURL.curl_easy_perform(self.ptr) != cURL.CURLE_OK) return error.CURLPerformFailed; + var httpCode: c_long = undefined; + if (cURL.curl_easy_getinfo(self.ptr, cURL.CURLINFO_RESPONSE_CODE, &httpCode) != cURL.CURLE_OK) + return error.CURLPerformFailed; + if (header_slist != null) cURL.curl_slist_free_all(header_slist); - var content = response_buffer.items; - var stream = json.TokenStream.init(content); + if (httpCode == 200) { + var content = response_buffer.items; + var stream = json.TokenStream.init(content); - @setEvalBranchQuota(10_000); - const res = json.parse(T, &stream, .{ .allocator = self.allocator, .ignore_unknown_fields = true }); + @setEvalBranchQuota(10_000); + const res = try json.parse(T, &stream, .{ .allocator = self.allocator, .ignore_unknown_fields = true }); - response_buffer.deinit(); - return res; + response_buffer.deinit(); + return Result(T){ .ok = res }; + } else { + response_buffer.deinit(); + + return Result(T){ .errorCode = httpCode }; + } } pub fn postJSON(self: *@This(), url: []const u8, data: anytype, headers: ?std.StringHashMap([]const u8)) anyerror![]const u8 {