aboutsummaryrefslogtreecommitdiff
path: root/lib/IRC/Client/Message.rakumod
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IRC/Client/Message.rakumod')
-rw-r--r--lib/IRC/Client/Message.rakumod180
1 files changed, 180 insertions, 0 deletions
diff --git a/lib/IRC/Client/Message.rakumod b/lib/IRC/Client/Message.rakumod
new file mode 100644
index 0000000..1e1ffb7
--- /dev/null
+++ b/lib/IRC/Client/Message.rakumod
@@ -0,0 +1,180 @@
+#! /usr/bin/env false
+
+use v6.d;
+
+use IRC::Grammar;
+
+#| A class to represent a message over IRC.
+unit class IRC::Client::Message;
+
+has Str $.servername;
+has Str $.nickname;
+has Str $.user;
+has Str $.host;
+has Str $.command;
+has Str @.params;
+has Bool $.ctcp = False;
+has $.irc;
+
+multi method new (
+ #| A string representing a line sent or received from an IRC server.
+ Str:D $line,
+
+ #| A reference the the IRC::Client handling the message.
+ $irc,
+) {
+ my $match = IRC::Grammar.parse($line);
+
+ # If the line doesn't match the IRC grammar, it's malformed and not up
+ # to IRC::Client to fix it.
+ die "Malformed message '$line'" if !?$match;
+
+ my $ctcp = False;
+ my @params = $match<params>.map(*.Str).Array;
+
+ my %prefix = $match<prefix>
+ .hash
+ .kv
+ .map(sub ($key, $value) { $key => $value.Str })
+ ;
+
+ if ($match<command> eq 'PRIVMSG'|'NOTICE') {
+ with ($match<params>.tail.Str) {
+ if ($_.comb[0, *-1].grep(* eq "\x[1]")) {
+ $ctcp = True;
+ @params[*-1] = $_.Str.substr(1, *-1);
+ } else {
+ @params[*-1] = $_.Str;
+ }
+ }
+ }
+
+ self.bless(
+ command => $match<command>.Str,
+ |%prefix,
+ :@params,
+ :$irc,
+ );
+}
+
+multi method new (
+ %params,
+) {
+ self.bless(|%params, params => %params<params>.list);
+}
+
+method gist
+{
+ @!params.tail
+}
+
+method prefix
+{
+ return $!servername if $!servername;
+
+ my $prefix = $!nickname;
+
+ if ($!host) {
+ if ($!user) {
+ $prefix = "$prefix!$!user";
+ }
+
+ $prefix = "$prefix@$!host";
+ }
+
+ $prefix;
+}
+
+method raku
+{
+ my $s = "$!command {@!params.join(' ')}";
+
+ with (self.prefix) { $s = ":$_ $s" }
+
+ given (@!params.elems) {
+ when 1 {
+ $s = "$s :{@!params[0]}"
+ }
+ default {
+ my @middle = @!params.head(*-1);
+ my $trailing = @!params.tail;
+
+ $s = "$s {@middle.join(' ')} :$trailing";
+ }
+ }
+
+
+ $s;
+}
+
+method words
+{
+ self.Str.words
+}
+
+method Hash
+{
+ %(
+ :$!servername,
+ :$!nickname,
+ :$!user,
+ :$!host,
+ :$!command,
+ :@!params,
+ :$!ctcp,
+ :$!irc,
+ )
+}
+
+method Str
+{
+ self.gist
+}
+
+#
+# Mutators
+#
+
+method set-param (
+ $index where { $_ ~~ Int:D|Code:D },
+ Str:D $value,
+) {
+ my %params = self.Hash;
+
+ %params<params>[$index] = $value;
+
+ self.new(|%params, params => %params<params>.list);
+}
+
+#
+# Convenience
+#
+
+method reply (
+ Str:D $message,
+) {
+ my $target = @!params[0] eq $!irc.nick ?? $!nickname !! @!params[0];
+
+ given ($!command) {
+ when 'PRIVMSG' { $!irc.privmsg($target, $message, :$!ctcp) }
+ when 'NOTICE' { $!irc.notice($target, $message, :$!ctcp) }
+ }
+}
+
+=begin pod
+
+=NAME IRC::Client::Message
+=AUTHOR Patrick Spek <~tyil/raku-devel@lists.sr.ht>
+=VERSION 0.0.0
+
+=head1 Synopsis
+
+=head1 Description
+
+=head1 Examples
+
+=head1 See also
+
+=end pod
+
+# vim: ft=perl6 noet