File Coverage

blib/lib/CXC/Astro/Regions/DS9/Variant.pm
Criterion Covered Total %
statement 112 114 98.2
branch 44 48 91.6
condition 22 29 75.8
subroutine 12 13 92.3
pod 0 4 0.0
total 190 208 91.3


line stmt bran cond sub pod time code
1             package CXC::Astro::Regions::DS9::Variant;
2              
3             # ABSTRACT: Generate DS9 Region classes
4              
5 3     3   211940 use v5.20;
  3         15  
6 3     3   24 use warnings;
  3         6  
  3         229  
7 3     3   588 use experimental 'signatures', 'postderef';
  3         1729  
  3         24  
8              
9             our $VERSION = '0.03';
10              
11 3     3   1474 use Module::Runtime 'module_notional_filename';
  3         2087  
  3         28  
12 3     3   1949 use Ref::Util qw( is_arrayref );
  3         4166  
  3         426  
13              
14              
15             use Package::Variant
16 3         24 importing => [ 'Moo', 'MooX::StrictConstructor' ],
17 3     3   15482 subs => [qw( has extends around with )];
  3         17663  
18              
19 3     3   504 use constant PREFIX => __PACKAGE__ =~ s/[^:]+$//r;
  3         20  
  3         5434  
20              
21             sub _croak {
22 0     0   0 require Carp;
23 0         0 goto \&Carp::croak;
24             }
25              
26              
27 42     42 0 1194 sub make_variant_package_name ( $, $package, % ) {
  42         81  
  42         102  
28 42         240 return PREFIX . ucfirst( $package );
29             }
30              
31              
32 42     42 0 180284 sub make_variant ( $, $, $region, %args ) {
  42         103  
  42         160  
  42         80  
33              
34 42   50     161 my $params = $args{params} // [];
35 42   50     155 my $props = $args{props} // [];
36 42   66     188 $region = $args{name} // $region;
37              
38 42 100 66     241 extends $args{extends}->@* if $args{extends} && $args{extends}->@*;
39              
40             # if a region has a text *parameter*, don't add a text *property*
41 42         14946 my $has_text_param;
42              
43 42         159 my @private = qw( label format render );
44              
45 42         123 for my $arg ( $params->@* ) {
46 138         837 my %has = ( is => 'ro', required => 1, $arg->%* );
47 138         497 my ( $name ) = delete @has{ 'name', @private };
48 138         629 has $name => %has;
49 138 100       68342 $has_text_param = !!1 if $name eq 'text';
50             }
51              
52 42         113 for my $arg ( $props->@* ) {
53 742         285172 my %has = ( is => 'ro', required => 0, $arg->%* );
54 742         2751 my ( $name ) = delete @has{ 'name', @private };
55 742 100 100     2441 next if $has_text_param && $name eq 'text';
56 740         2742 has $name => %has;
57             }
58              
59 57     57   332211 install render => sub ( $self ) {
  57         105  
  57         115  
60 57         105 my @output;
61 57 100       214 push @output, q{#} if $args{comment};
62 57 50       338 push @output, ( $self->include ? q{} : q{-} ) . $region;
63 57         174 push @output, params( $self, $params );
64 57         152 my @props = props( $self, $props, has_text_param => $has_text_param );
65              
66 57 100       170 push @output, q{#}, @props if @props;
67              
68 57         537 return join q{ }, @output;
69 42         18165 };
70              
71 42 100 66     1153 around $args{around}->@* if $args{around} && $args{around}->@*;
72 42 100 66     1457 with $args{with}->@* if $args{with} && $args{with}->@*;
73              
74             }
75              
76 57     57 0 104 sub params ( $self, $params ) {
  57         104  
  57         75  
  57         76  
77 57         81 my @output;
78              
79 57         156 for my $param ( $params->@* ) {
80              
81             # if the caller doesn't want this rendered, don't
82 158 100 100     675 next if !( $param->{render} // !!1 );
83              
84 156         283 my $name = $param->{name};
85 156         469 my @values = ( $self->$name );
86 156 100       325 next if !defined $values[0];
87              
88 145 100       319 if ( defined( my $format = $param->{format} ) ) {
89 1         5 push @output, $format->( 'param', $name, \@values );
90 1         3 next;
91             }
92              
93 144         215 my @param_values;
94              
95 144         263 while ( @values ) {
96 372         553 my $value = shift @values;
97 372 100       773 if ( is_arrayref( $value ) ) {
98 111         272 unshift @values, $value->@*;
99 111         251 next;
100             }
101 261         633 push @param_values, $value;
102             }
103              
104 144 100 100     446 if ( @param_values == 1 && defined( my $label = $param->{label} ) ) {
105 6         28 push @output, $label . q{=} . $param_values[0];
106             }
107             else {
108 138         416 push @output, @param_values;
109             }
110             }
111              
112 57         306 return @output;
113             }
114              
115 57     57 0 113 sub props ( $self, $props, %args ) {
  57         86  
  57         81  
  57         123  
  57         74  
116              
117 57         79 my @output;
118              
119 57         108 for my $prop ( $props->@* ) {
120              
121             # if the caller doesn't want this rendered, don't
122 1044 50 50     2966 next if !( $prop->{render} // !!1 );
123              
124 1044         1745 my $name = $prop->{name};
125              
126 1044 100       1826 next if $name eq 'include'; # this results in a prefix to the
127             # start of the region spec
128              
129 987 100 100     1827 next if $name eq 'text' && $args{has_text_param};
130              
131 986 100       1662 my $label = exists $prop->{label} ? $prop->{label} : $name;
132 986         2299 my @values = ( grep defined, $self->$name );
133 986 100       1911 next unless @values;
134              
135 55 100       137 if ( defined( my $format = $prop->{format} ) ) {
136 16         63 push @output, $format->( 'prop', $label, \@values );
137 16         64 next;
138             }
139              
140 39         71 my @prop_values;
141              
142 39         75 while ( @values ) {
143 57         96 my $value = shift @values;
144 57 100       125 if ( is_arrayref( $value ) ) {
145 9         28 unshift @values, $value->@*;
146 9         75 next;
147             }
148 48         120 push @prop_values, $value;
149             }
150              
151 39 50       79 if ( @prop_values ) {
152              
153 39 100       96 if ( !defined $label ) {
    100          
154 15         46 push @output, @prop_values;
155             }
156             elsif ( @prop_values == 1 ) {
157 23         73 push @output, $label . q{=} . $prop_values[0];
158             }
159             else {
160 1 50       7 push @output, "$label=" if defined $label;
161 1         5 push @output, @prop_values;
162             }
163             }
164             }
165              
166 57         187 return @output;
167             }
168              
169             1;
170              
171             #
172             # This file is part of CXC-Astro-Regions
173             #
174             # This software is Copyright (c) 2023 by Smithsonian Astrophysical Observatory.
175             #
176             # This is free software, licensed under:
177             #
178             # The GNU General Public License, Version 3, June 2007
179             #
180              
181             __END__