From b6da79a0bc1289f2a6064a6b3ffcd0c2333f2c97 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Wed, 5 May 2021 11:03:32 +0200 Subject: Initial commit --- lib/IRC/Client/Message.rakumod | 180 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 lib/IRC/Client/Message.rakumod (limited to 'lib/IRC/Client/Message.rakumod') 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.map(*.Str).Array; + + my %prefix = $match + .hash + .kv + .map(sub ($key, $value) { $key => $value.Str }) + ; + + if ($match eq 'PRIVMSG'|'NOTICE') { + with ($match.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.Str, + |%prefix, + :@params, + :$irc, + ); +} + +multi method new ( + %params, +) { + self.bless(|%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[$index] = $value; + + self.new(|%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 -- cgit v1.1