File Coverage

blib/lib/Zodiac/Angle.pm
Criterion Covered Total %
statement 63 71 88.7
branch 25 30 83.3
condition 3 3 100.0
subroutine 10 11 90.9
pod 3 3 100.0
total 104 118 88.1


line stmt bran cond sub pod time code
1             package Zodiac::Angle;
2              
3 5     5   596405 use strict;
  5         11  
  5         170  
4 5     5   19 use warnings;
  5         8  
  5         347  
5              
6 5     5   2647 use Class::Utils qw(set_params);
  5         59588  
  5         138  
7 5     5   438 use Error::Pure qw(err);
  5         2363  
  5         272  
8 5     5   2084 use List::Util 1.33 qw(none);
  5         101  
  5         283  
9 5     5   26 use Readonly;
  5         25  
  5         227  
10 5     5   7470 use Unicode::UTF8 qw(decode_utf8);
  5         2193  
  5         5486  
11              
12             Readonly::Array our @SIGN_TYPES => qw(ascii sign struct);
13             Readonly::Hash our %ZODIAC => (
14             1 => {
15             'sign' => decode_utf8('♈'), # Aries/Beran
16             'ascii' => 'ar',
17             'ascii_long' => 'aries',
18             },
19             2 => {
20             'sign' => decode_utf8('♉'), # Taurus/Býk
21             'ascii' => 'ta',
22             'ascii_long' => 'taurus',
23             },
24             3 => {
25             'sign' => decode_utf8('♊'), # Gemini/Blíženci
26             'ascii' => 'ge',
27             'ascii_long' => 'gemini',
28             },
29             4 => {
30             'sign' => decode_utf8('♋'), # Cancer/Rak
31             'ascii' => 'cn',
32             'ascii_long' => 'cancer',
33             },
34             5 => {
35             'sign' => decode_utf8('♌'), # Leo/Lev
36             'ascii' => 'le',
37             'ascii_long' => 'leo',
38             },
39             6 => {
40             'sign' => decode_utf8('♍'), # Virgo/Panna
41             'ascii' => 'vi',
42             'ascii_long' => 'virgo',
43             },
44             7 => {
45             'sign' => decode_utf8('♎'), # Libra/Váhy
46             'ascii' => 'li',
47             'ascii_long' => 'libra',
48             },
49             8 => {
50             'sign' => decode_utf8('♏'), # Scorpio/Štír
51             'ascii' => 'sc',
52             'ascii_long' => 'scorpio',
53             },
54             9 => {
55             'sign' => decode_utf8('♐'), # Sagittarius/Střelec
56             'ascii' => 'sa',
57             'ascii_long' => 'sagittarius',
58             },
59             10 => {
60             'sign' => decode_utf8('♑'), # Capricorn/Kozoroh
61             'ascii' => 'cp',
62             'ascii_long' => 'capricorn',
63             },
64             11 => {
65             'sign' => decode_utf8('♒'), # Aquarius/Vodnář
66             'ascii' => 'aq',
67             'ascii_long' => 'aquarius',
68             },
69             12 => {
70             'sign' => decode_utf8('♓'), # Pisces/Ryby
71             'ascii' => 'pi',
72             'ascii_long' => 'pisces',
73             },
74             );
75             Readonly::Scalar our $SPACE => ' ';
76             Readonly::Scalar our $SEP => '|';
77              
78             our $VERSION = 0.07;
79              
80             # Constructor.
81             sub new {
82 2     2 1 380765 my ($class, @params) = @_;
83              
84             # Create object.
85 2         6 my $self = bless {}, $class;
86              
87             # Process parameters.
88 2         28 set_params($self, @params);
89              
90 2         17 return $self;
91             }
92              
93             sub angle2zodiac {
94 20     20 1 12202 my ($self, $angle, $opts_hr) = @_;
95              
96             # Options.
97 20 100 100     74 if (! defined $opts_hr || ! exists $opts_hr->{'minute'}) {
98 13         20 $opts_hr->{'minute'} = 1;
99             }
100 20 100       41 if (! exists $opts_hr->{'second'}) {
101 16         23 $opts_hr->{'second'} = 0;
102             }
103 20 100       35 if (! exists $opts_hr->{'second_round'}) {
104 19         25 $opts_hr->{'second_round'} = 4;
105             }
106 20 100       38 if (! exists $opts_hr->{'sign_type'}) {
107 15         23 $opts_hr->{'sign_type'} = 'sign';
108             }
109 20 100   37   121 if (none { $opts_hr->{'sign_type'} eq $_ } @SIGN_TYPES) {
  37         264  
110 1         9 err "Parameter 'sign_type' is bad. Possible values are 'sign', 'ascii' and 'struct'.";
111             }
112              
113 19         155 my $ret = {};
114              
115             # Full angle degree.
116 19         34 my $full_angle_degree = int($angle);
117 19         27 $angle -= $full_angle_degree;
118 19         23 $angle *= 60;
119              
120             # Angle minute.
121 19 100       37 if ($opts_hr->{'minute'}) {
122 17         26 $ret->{'angle_minute'} = int($angle);
123 17         21 $angle -= $ret->{'angle_minute'};
124 17         26 $angle *= 60;
125             }
126              
127             # Angle second.
128 19 100       34 if ($opts_hr->{'second'}) {
129 3         7 my $print_format = '%0.'.$opts_hr->{'second_round'}.'f';
130 3         26 $ret->{'angle_second'} = sprintf($print_format, $angle);
131             }
132              
133             # Angle sign.
134 19         31 $ret->{'sign'} = int($full_angle_degree / 30);
135              
136             # Angle degree in sign.
137 19         27 $ret->{'angle_degree'} = $full_angle_degree - ($ret->{'sign'} * 30);
138              
139             # Output.
140 19         21 my $zodiac_angle;
141              
142             # Output with sign (UTF-8).
143 19 100       40 if ($opts_hr->{'sign_type'} eq 'sign') {
    50          
144             $zodiac_angle = $ret->{'angle_degree'}.decode_utf8('°').
145 15         83 $ZODIAC{$ret->{'sign'} + 1}->{'sign'};
146 15 100       178 if ($opts_hr->{'minute'}) {
147 14         29 $zodiac_angle .= $ret->{'angle_minute'}.decode_utf8("′");
148 14 100       27 if ($opts_hr->{'second'}) {
149 1         4 $zodiac_angle .= $ret->{'angle_second'}.decode_utf8("′′");
150             }
151             }
152              
153             # Output with ascii.
154             } elsif ($opts_hr->{'sign_type'} eq 'ascii') {
155             $zodiac_angle = $ret->{'angle_degree'}.$SPACE.
156 4         17 $ZODIAC{$ret->{'sign'} + 1}->{'ascii'};
157 4 100       42 if ($opts_hr->{'minute'}) {
158 3         7 $zodiac_angle .= $SPACE.$ret->{'angle_minute'}."'";
159 3 100       4 if ($opts_hr->{'second'}) {
160 2         4 $zodiac_angle .= $ret->{'angle_second'}."''";
161             }
162             }
163              
164             # Structure.
165             } else {
166             $zodiac_angle = $ret->{'angle_degree'}.decode_utf8('°').$SEP.
167 0         0 $ZODIAC{$ret->{'sign'} + 1}->{'ascii_long'};
168 0 0       0 if ($opts_hr->{'minute'}) {
169 0         0 $zodiac_angle .= $SEP.$ret->{'angle_minute'}.decode_utf8("′");
170 0 0       0 if ($opts_hr->{'second'}) {
171 0         0 $zodiac_angle .= $SEP.$ret->{'angle_second'}.decode_utf8("′′");
172             }
173             }
174             }
175              
176 19         61 return $zodiac_angle;
177             }
178              
179             sub zodiac2angle {
180 0     0 1   my ($self, $zodiac_angle) = @_;
181              
182             # TODO
183 0           my $angle;
184              
185 0           return $angle;
186             }
187              
188             1;
189              
190             __END__