package Data::QRCode; use Moo; use Data::QRCode::Input; use Data::QRCode::Result; use Data::QRCode::Types qw(QRCodeEC QRCodeMode); use Types::Standard qw(Str Int); use namespace::clean; # ABSTRACT: qrcodes in C # VERSION has error_correction_level => ( is => 'ro', isa => QRCodeEC, coerce => 1, default => Data::QRCode::Input::ECLEVEL_M, ); has mode => ( is => 'ro', isa => QRCodeMode, coerce => 1, default => Data::QRCode::Input::MODE_8, ); has version => ( is => 'rwp', isa => Int, default => 0, ); has input_data => ( is => 'ro', required => 1, isa => Str, ); around BUILDARGS => sub { my ($orig,$class,@args) = @_; return { input_data => $args[0] } if @args == 1 && !ref $args[0]; return $class->$orig(@args); }; has _result => ( is => 'lazy', init_arg => undef, handles => [ qw(width data_at) ], ); sub _build__result { my ($self) = @_; my $input = Data::QRCode::Input->new(); $input->error_correction_level($self->error_correction_level); $input->version($self->version); $input->append($self->mode,$self->input_data); my $ret = Data::QRCode::Result->new($input); $self->_set_version($ret->version); return $ret; } sub map { my ($self,$code) = @_; my $r = $self->_result; my @result; for my $y (0..$r->width-1) { push @result,[]; for my $x (0..$r->width-1) { # use the internal function to avoid re-checking the x/y # bounds my $raw_data = $r->_data_at($x,$y); my $hash_data = Data::QRCode::Result::_data_hash($raw_data); push @{$result[-1]}, $code->($hash_data,$raw_data); } } return \@result; } 1;