Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Last active August 25, 2024 12:57
Show Gist options
  • Save ityonemo/c662c329011bfae7c28aa12cbf2386b2 to your computer and use it in GitHub Desktop.
Save ityonemo/c662c329011bfae7c28aa12cbf2386b2 to your computer and use it in GitHub Desktop.
Enterprise LibCurl with Zigler
Mix.install([
{:zigler, "~> 0.13"}
])
Logger.configure(level: :warning)
defmodule Main do
use Zig,
otp_app: :zigler,
c: [link_lib: {:system, "curl"}],
nifs: [example: [:dirty_io]]
~Z"""
const std = @import("std");
const curl = @cImport({
@cInclude("curl/curl.h");
});
const beam = @import("beam");
const EzOptions = enum (c_int) {
user_agent = curl.CURLOPT_USERAGENT,
url = curl.CURLOPT_URL,
};
const ExampleOptions = struct{
user_agent: ?[]const u8 = "libcurl",
url: ?[]const u8 = null
};
pub fn example(opts: ExampleOptions) !void {
const c = curl.curl_easy_init() orelse return error.initialization_failure;
const tags = comptime std.meta.tags(EzOptions);
inline for (tags) | field | {
if (@field(opts, @tagName(field))) | opt | {
// annoying, perform null termination, better support for null-terminated
// slices will drop in zigler 0.14
const opt_str: [:0]u8 = try beam.allocator.allocWithOptions(u8, opt.len + 1, null, 0);
defer beam.allocator.free(opt_str);
@memcpy(opt_str[0..opt.len], opt);
opt_str[opt.len] = 0;
_ = curl.curl_easy_setopt(c, @intFromEnum(field), opt_str.ptr);
}
}
_ = curl.curl_easy_perform(c);
}
"""
end
Main.example(url: "https://httpbin.org/user-agent")
Main.example(url: "https://httpbin.org/user-agent", user_agent: "foobarbaz")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment