chore: make stuff work
This commit is contained in:
parent
936bf470c7
commit
1e4c90822a
4 changed files with 267 additions and 117 deletions
114
src/main.zig
114
src/main.zig
|
|
@ -1,9 +1,13 @@
|
|||
const std = @import("std");
|
||||
const zigeru = @import("zigeru");
|
||||
|
||||
const zircon = @import("zircon");
|
||||
const zigeru = @import("zigeru");
|
||||
|
||||
const Bot = zigeru.bot.Bot;
|
||||
const Error = zigeru.bot.Error;
|
||||
const BotCommand = zigeru.bot.Command;
|
||||
const AdminCommand = zigeru.bot.AdminCommand;
|
||||
const BotMessage = zigeru.bot.Message;
|
||||
|
||||
var debug_allocator = std.heap.DebugAllocator(.{}).init;
|
||||
|
||||
|
|
@ -26,30 +30,23 @@ pub fn main() !void {
|
|||
defer client.deinit();
|
||||
|
||||
var bot_adapter = try BotAdapter.init(allocator);
|
||||
const adapter = bot_adapter.adapter();
|
||||
|
||||
defer bot_adapter.deinit();
|
||||
client.register_message_closure(bot_adapter.closure());
|
||||
// Connect to the IRC server and perform registration.
|
||||
try client.connect();
|
||||
try client.register();
|
||||
try client.join("#eru-tests");
|
||||
try client.join("#eru-admin");
|
||||
|
||||
// Enter the main loop that keeps reading incoming IRC messages forever.
|
||||
// The client loop accepts a LoopConfig struct with two optional fields.
|
||||
//
|
||||
// These two fields, .msg_callback and .spawn_thread are callback pointers.
|
||||
// You set them to custom functions you define to customize the main loop.
|
||||
//
|
||||
// .msg_callback lets you answer any received IRC messages with another one.
|
||||
//
|
||||
// .spawn_thread lets you tweak if you spawn a thread to run .msg_callback.
|
||||
client.loop(.{ .msg_callback = adapter.callbackFn }) catch |err| {
|
||||
std.debug.print("eru exited with error: {}", .{err});
|
||||
client.loop(.{}) catch |err| {
|
||||
std.debug.print("eru exited with error: {}\n", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
pub const Adapter = struct {
|
||||
ptr: ?*anyopaque,
|
||||
callbackFn: *const fn (?*anyopaque, zircon.Message) ?zircon.Message,
|
||||
ptr: *anyopaque,
|
||||
callbackFn: *const fn (*anyopaque, zircon.Message) ?zircon.Message,
|
||||
};
|
||||
|
||||
pub const BotAdapter = struct {
|
||||
|
|
@ -70,47 +67,66 @@ pub const BotAdapter = struct {
|
|||
pub fn callback(self: *BotAdapter, message: zircon.Message) ?zircon.Message {
|
||||
switch (message) {
|
||||
.PRIVMSG => |msg| {
|
||||
if (Command.parse(msg.prefix, msg.targets, msg.text)) |command| {
|
||||
return command.handle(&self.bot);
|
||||
std.log.debug("received message: nick {?s}, user: {?s}, host: {?s}, targets: {s}, text: {s}", .{
|
||||
msg.prefix.?.nick,
|
||||
msg.prefix.?.user,
|
||||
msg.prefix.?.host,
|
||||
msg.targets,
|
||||
msg.text,
|
||||
});
|
||||
const nick = if (msg.prefix) |prefix| if (prefix.nick) |nick| nick else "unknown" else "unknown";
|
||||
if (BotCommand.parse(nick, msg.text)) |command| {
|
||||
return self.bot.execute(&command, msg.prefix, msg.targets) catch |err| {
|
||||
const err_msg = switch (err) {
|
||||
Error.NoMessage => "no matching message",
|
||||
Error.OutOfMemory => "out of memory",
|
||||
Error.WriteFailed => "write failed",
|
||||
};
|
||||
return .{ .PRIVMSG = .{ .prefix = msg.prefix, .targets = "#eru-admin", .text = err_msg } };
|
||||
};
|
||||
}
|
||||
self.bot.hear(zigeru.bot.Message{
|
||||
.author = msg.prefix.?.nick orelse "unknown",
|
||||
.timestamp = std.time.timestamp(),
|
||||
.content = msg.text,
|
||||
if (AdminCommand.parse(msg.text)) |command| {
|
||||
return self.bot.execute_admin(&command, msg.prefix, "#eru-admin") catch |err| {
|
||||
const err_msg = switch (err) {
|
||||
Error.NoMessage => "no matching message",
|
||||
Error.OutOfMemory => "out of memory",
|
||||
Error.WriteFailed => "write failed",
|
||||
};
|
||||
return .{ .PRIVMSG = .{ .prefix = msg.prefix, .targets = "#eru-admin", .text = err_msg } };
|
||||
};
|
||||
}
|
||||
self.bot.hear(BotMessage.new_owned(
|
||||
self.allocator,
|
||||
std.time.timestamp(),
|
||||
msg.prefix.?.nick orelse "unknown",
|
||||
msg.targets,
|
||||
msg.text,
|
||||
) catch |err| {
|
||||
const error_msg = switch (err) {
|
||||
Error.OutOfMemory => "eru failed to listen to a message with error: no memory",
|
||||
else => unreachable,
|
||||
};
|
||||
return zircon.Message{
|
||||
.PRIVMSG = .{ .targets = "jassob", .text = error_msg },
|
||||
};
|
||||
});
|
||||
},
|
||||
else => {},
|
||||
else => {
|
||||
std.log.debug("received unknown message {}", .{message});
|
||||
},
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn adapter(self: *BotAdapter) Adapter {
|
||||
pub fn erased_callback(self: *anyopaque, message: zircon.Message) ?zircon.Message {
|
||||
const a: *@This() = @ptrCast(@alignCast(self));
|
||||
return a.callback(message);
|
||||
}
|
||||
|
||||
pub fn closure(self: *BotAdapter) zircon.MessageClosure {
|
||||
return .{
|
||||
.ptr = self,
|
||||
.callbackFn = self.callback,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Command = struct {
|
||||
command: BotCommand,
|
||||
prefix: ?zircon.Prefix,
|
||||
targets: []const u8,
|
||||
|
||||
pub fn parse(prefix: ?zircon.Prefix, targets: []const u8, text: []const u8) ?Command {
|
||||
const nick = prefix.?.nick.?;
|
||||
const command = BotCommand.parse(nick, text) orelse return null;
|
||||
return .{
|
||||
.command = command,
|
||||
.prefix = prefix,
|
||||
.targets = targets,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn handle(self: Command, bot: *Bot) ?zircon.Message {
|
||||
return bot.execute(&self.command, self.prefix, self.targets) catch |err| {
|
||||
std.debug.print("Failed to handle {}: {}", .{ self, err });
|
||||
return null;
|
||||
.callbackFn = BotAdapter.erased_callback,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
@ -136,5 +152,5 @@ test "substitute" {
|
|||
};
|
||||
const response = bot_adapter.callback(cmd_msg);
|
||||
try std.testing.expect(response != null);
|
||||
try std.testing.expectEqualStrings("hello zig", response.?.PRIVMSG.text);
|
||||
try std.testing.expectEqualStrings("jassob: \"hello zig\"", response.?.PRIVMSG.text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue