diff options
| -rw-r--r-- | challenge-062/markus-holzer/raku/ch-1.raku | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/challenge-062/markus-holzer/raku/ch-1.raku b/challenge-062/markus-holzer/raku/ch-1.raku new file mode 100644 index 0000000000..098d35f0d0 --- /dev/null +++ b/challenge-062/markus-holzer/raku/ch-1.raku @@ -0,0 +1,62 @@ +# This should really follow the spec or use something from CPAN +class Mail +{ + has Str $.address; + has Str $.domain; + has Str $.mailbox; + has Str $.norm; + has Bool $.valid; + + method Str { $!address } + + submethod TWEAK( :$!address ) + { + my $index = $!address.index: '@'; + return unless $index && 0 < $index < $!address.chars - 1; + + $!mailbox = $!address.substr: 0, $index; + $!domain = lc $!address.substr: $index + 1, *; + $!norm = $!mailbox ~ '@' ~ $!domain; + $!valid = True; + } +} + +subset FileIsReadable where { .IO.f && .IO.e && .IO.r } +subset FilesAreReadable where { .all ~~ FileIsReadable } + +#| read from files +multi sub MAIN( + Bool :$u, #= unique. filters duplicates + *@files where FilesAreReadable #= files containing email addresses, 1 per line +) { + output-email-addresses $u, sort-mail-addresses @files.map: *.IO.open( :r ) } + +#| read from STDIN +multi sub MAIN( Bool :$u ) { + output-email-addresses $u, sort-mail-addresses $*IN } + +# catch bad arguments +multi sub MAIN( Bool :$u, *@ ) is hidden-from-USAGE { + $*USAGE.say } + +sub output-email-addresses( $unique, @addresses ) { + .address.say for $unique + ?? @addresses.squish( as => *.norm ) + !! @addresses } + +multi sub sort-mail-addresses( $handles where { .cache.all ~~ IO::Handle } ) { + $handles + .map( | *.lines ) + .map( &make-mail ) + .grep( &valid-mail ) + .sort( &sort-mail ) } + +sub make-mail( $address ) { + Mail.new( :$address ) } + +sub valid-mail( $mail ) { + $mail.valid || + $*ERR.say("Bad data <$mail>") && False } + +sub sort-mail( $a, $b ) { + $a.domain cmp $b.domain || $a.mailbox cmp $b.mailbox } |
