File Coverage

blib/lib/Games/Go/AGA/DataObjects/Directives.pm
Criterion Covered Total %
statement 56 101 55.4
branch 10 32 31.2
condition 2 12 16.6
subroutine 11 19 57.8
pod 9 12 75.0
total 88 176 50.0


line stmt bran cond sub pod time code
1             #===============================================================================
2             #
3             # FILE: Games::Go::AGA::DataObjects::Directives.pm
4             #
5             # USAGE: use Games::Go::AGA::DataObjects::Directives;
6             #
7             # PODNAME: Games::Go::AGA::DataObjects::Directives
8             # ABSTRACT: model directives information from an AGA register.tde file
9             #
10             # AUTHOR: Reid Augustin (REID),
11             # COMPANY: LucidPort Technology, Inc.
12             # CREATED: 11/19/2010 03:13:05 PM PST
13             #===============================================================================
14              
15 2     2   17530 use strict;
  2         4  
  2         92  
16 2     2   12 use warnings;
  2         2  
  2         85  
17              
18             package Games::Go::AGA::DataObjects::Directives;
19              
20 2     2   566 use Mouse;
  2         22869  
  2         14  
21 2     2   1406 use Games::Go::AGA::DataObjects::Types qw( is_Rank is_Rating );
  2         5  
  2         180  
22 2     2   498 use Games::Go::AGA::Parse::Util qw( Rank_to_Rating );
  2         840  
  2         2463  
23              
24             our $VERSION = '0.107'; # VERSION
25              
26             # has 'keys' => (
27             # is => 'ro',
28             # isa => 'ArrayRef[Str]',
29             # default => sub { [] },
30             # );
31             # has 'values' => (
32             # is => 'ro',
33             # isa => 'ArrayRef[Str]',
34             # default => sub { [] },
35             # );
36              
37             has 'change_callback' => (
38             isa => 'Maybe[CodeRef]',
39             is => 'rw',
40             default => sub { sub { } }
41             );
42              
43             sub BUILD {
44 2     2 1 6 my ($self) = @_;
45 2         18 $self->{keys} = []; # empty arrays
46 2         10 $self->{values} = [];
47             }
48              
49             sub changed {
50 0     0 0 0 my ($self) = @_;
51              
52 0 0       0 &{$self->change_callback}($self) if ($self->{change_callback});
  0         0  
53             }
54              
55             sub directives {
56 0     0 1 0 my ($self) = @_;
57              
58             return wantarray
59 0         0 ? @{$self->{keys}}
  0         0  
60 0 0       0 : scalar @{$self->{keys}};
61             }
62              
63             sub get_directive_at_idx {
64 0     0 1 0 my ($self, $idx) = @_;
65              
66 0         0 croak("$idx out of range") if (($idx < 0) or
67 0 0 0     0 ($idx >= @{$self->{keys}}));
68 0         0 return ($self->{keys}[$idx], $self->{values}[$idx]);
69             }
70              
71             sub set_directive_at_idx {
72 0     0 1 0 my ($self, $idx, $key, $value) = @_;
73              
74 0         0 croak("$idx out of range") if (($idx < 0) or
75 0 0 0     0 ($idx >= @{$self->{keys}}));
76 0 0       0 $value = $self->_munge_BAND_BREAKS($value) if ($key eq 'BAND_BREAKS');
77 0         0 $self->{keys}[$idx] = $key;
78 0         0 $self->{values}[$idx] = $value;
79 0         0 $self->changed;
80 0         0 return $self;
81             }
82              
83             sub delete_directive_at_idx {
84 0     0 1 0 my ($self, $idx) = @_;
85              
86 0 0       0 $idx = 0 if ($idx < 0);
87 0 0       0 $idx = $#{$self->{keys}} if ($idx > $#{$self->{keys}});
  0         0  
  0         0  
88              
89 0         0 splice(@{$self->{keys}} , $idx, 1);
  0         0  
90 0         0 splice(@{$self->{values}}, $idx, 1);
  0         0  
91 0         0 $self->changed;
92 0         0 return $self;
93             }
94              
95             sub _munge_BAND_BREAKS {
96 1     1   2 my ($self, $value) = @_;
97              
98 1 50       3 return '' if ($value eq ''); #special case to mark empty breaks
99 1         7 return join ' ', # read from the bottom up:
100 2         5 sort { $b <=> $a } # sort stronger bands higher
101 2 50       4 grep { $_ } # defined and truthy
    50          
102 2         3 map { is_Rank($_) # is it a valid Rank?
103             ? int Rank_to_Rating($_) # if so, convert to a Rating and integerize
104             : is_Rating($_) # is it a Rating?
105             ? $_ # pass through untouched
106             : undef } # filter out everything else
107 1         7 grep { $_ } # defined and truthy
108             split(/[^\ddDkK\.\-]+/, $value); # split into ranks/ratings
109             }
110              
111             sub insert_directive_above {
112 5     5 1 8 my ($self, $idx, $key, $value) = @_;
113              
114 5 50 33     40 if (not defined $idx or
  0   33     0  
115             $idx < 0 or
116             $idx >= @{$self->{keys}}) {
117 5         6 $idx = @{$self->{keys}}; # add to end
  5         11  
118             }
119              
120 5 100       23 $value = $self->_munge_BAND_BREAKS($value) if ($key eq 'BAND_BREAKS');
121 5         8 splice(@{$self->{keys}} , $idx, 0, $key);
  5         17  
122 5         7 splice(@{$self->{values}}, $idx, 0, $value);
  5         13  
123 5         18 $self->changed;
124 5         26 return $self;
125             }
126              
127             sub delete_directive {
128 0     0 1 0 my ($self, $key) = @_;
129              
130 0         0 my $keys = $self->{keys};
131              
132 0         0 for (my $ii = $#{$keys}; $ii >= 0; $ii--) {
  0         0  
133 0 0       0 if (uc $key eq uc $keys->[$ii]) {
134 0         0 $self->delete_directive_at_idx($ii);
135 0         0 $self->changed;
136             }
137             }
138 0         0 return $self;
139             }
140              
141             sub get_directive_values { # for backwards compatibility
142 0     0 0 0 shift->get_directive_value(@_);
143             }
144              
145             sub get_directive_value {
146 20     20 1 19 my ($self, $key) = @_;
147              
148 20         21 my $keys = $self->{keys};
149 20         22 $key = uc ($key);
150 20         14 foreach my $ii (0 .. $#{$keys}) {
  20         39  
151 98 100       163 if (uc($keys->[$ii]) eq $key) {
152 19         20 my $val = $self->{values}[$ii];
153 19 50       24 $val = 1 if (not $val); # booleans (key but no value)
154 19         55 return $val;
155             }
156             }
157 1         3 return; # undef
158             }
159              
160             sub set_directive_value {
161 5     5 1 2927 my ($self, $key, $val) = @_;
162              
163 5         8 my $keys = $self->{keys};
164 5         10 $key = uc ($key);
165 5         7 foreach my $ii (0 .. $#{$keys}) {
  5         15  
166 10 50       27 if (uc($keys->[$ii]) eq $key) {
167 0         0 return $self->set_directive_at_idx ($ii, $key, $val);
168             }
169             }
170             # not found? add to the end
171 5         25 return $self->insert_directive_above (-1, $key, $val);
172             }
173              
174             sub fprint {
175 0     0 0   my ($self, $fh) = @_;
176              
177 0           for my $ii (0 .. $#{$self->{keys}}) {
  0            
178 0           $fh->print("## $self->{keys}[$ii] $self->{values}[$ii]\n");
179             }
180             }
181              
182 2     2   15 no Mouse;
  2         3  
  2         12  
183             __PACKAGE__->meta->make_immutable;
184              
185             1;
186              
187             __END__