package Enigmatic::Types;
use DAKKAR::p;
use MooseX::Types -declare => [qw(Letter WiringMap ReflWiringMap RotorPos)];
use MooseX::Types::Moose qw(Str Int);
use MooseX::Types::Structured qw(Map);
subtype Letter,
as Str,
where { /[A-Z]/ };
subtype WiringMap,
as Map[Letter,Letter],
where {
my $in = $_->keys->sort->join;
my $out = $_->values->sort->join;
$in eq $out and $in eq ['A'..'Z']->join;
};
subtype ReflWiringMap,
as WiringMap,
where {
my %reverse; @reverse{values %$_} = keys %$_;
(join '',@reverse{keys %$_}) eq $_->values->join;
};
sub _coerce_wiring {
my @out = $_[0]->uc->split(qr//)->flatten;
croak "invalid wiring string <$_>"
unless @out == 26;
my %ret;
@ret{'A'..'Z'}=@out;
\%ret;
}
coerce WiringMap,
from Str,
via \&_coerce_wiring;
coerce ReflWiringMap,
from Str,
via \&_coerce_wiring;
subtype RotorPos,
as Int,
where { $_ >=0 and $_ <= 26 };