File Coverage

blib/lib/Lingua/SWA/Num2Word.pm
Criterion Covered Total %
statement 28 56 50.0
branch 2 26 7.6
condition 4 41 9.7
subroutine 9 11 81.8
pod 3 3 100.0
total 46 137 33.5


line stmt bran cond sub pod time code
1             # For Emacs: -*- mode:cperl; eval: (folding-mode 1); coding:utf-8 -*-
2              
3             package Lingua::SWA::Num2Word;
4             # ABSTRACT: Number to word conversion in Swahili
5              
6 1     1   87964 use 5.16.0;
  1         3  
7 1     1   4 use utf8;
  1         2  
  1         9  
8 1     1   21 use warnings;
  1         1  
  1         59  
9              
10             # {{{ use block
11              
12 1     1   5 use Carp;
  1         1  
  1         78  
13 1     1   481 use Export::Attrs;
  1         8239  
  1         6  
14 1     1   597 use Readonly;
  1         3243  
  1         372  
15              
16             # }}}
17             # {{{ variable declarations
18              
19             my Readonly::Scalar $COPY = 'Copyright (c) PetaMem, s.r.o. 2002-present';
20             our $VERSION = '0.2603300';
21              
22             # }}}
23              
24             # {{{ num2swa_cardinal convert number to text
25              
26             sub num2swa_cardinal :Export {
27 2     2 1 131655 my $positive = shift;
28              
29 2 50 33     25 croak 'You should specify a number from interval [0, 999_999_999]'
      33        
      33        
30             if !defined $positive
31             || $positive !~ m{\A\d+\z}xms
32             || $positive < 0
33             || $positive > 999_999_999;
34              
35 2         9 my @ones = qw(sifuri moja mbili tatu nne tano sita saba nane tisa);
36 2         7 my @tens = qw(kumi ishirini thelathini arobaini hamsini sitini sabini themanini tisini);
37              
38 2 50 33     15 return $ones[$positive] if ($positive >= 0 && $positive < 10); # 0 .. 9
39 0 0         return 'kumi' if ($positive == 10); # 10
40 0 0 0       return 'kumi na ' . $ones[$positive - 10]
41             if ($positive > 10 && $positive < 20); # 11 .. 19
42              
43 0           my $out;
44             my $remain;
45              
46 0 0 0       if ($positive > 19 && $positive < 100) { # 20 .. 99
    0 0        
    0 0        
    0 0        
47 0           my $ten_idx = int($positive / 10) - 1; # tens[0]=kumi, tens[1]=ishirini
48 0           $remain = $positive % 10;
49              
50 0           $out = $tens[$ten_idx];
51 0 0         $out .= ' na ' . $ones[$remain] if ($remain);
52             }
53             elsif ($positive > 99 && $positive < 1000) { # 100 .. 999
54 0           my $hun = int($positive / 100);
55 0           $remain = $positive % 100;
56              
57 0           $out = 'mia ' . $ones[$hun];
58 0 0         $out .= ' na ' . num2swa_cardinal($remain) if ($remain);
59             }
60             elsif ($positive > 999 && $positive < 1_000_000) { # 1000 .. 999_999
61 0           my $thou = int($positive / 1000);
62 0           $remain = $positive % 1000;
63              
64 0           $out = 'elfu ' . num2swa_cardinal($thou);
65 0 0         $out .= ' na ' . num2swa_cardinal($remain) if ($remain);
66             }
67             elsif ($positive > 999_999 && $positive < 1_000_000_000) { # 1_000_000 .. 999_999_999
68 0           my $mil = int($positive / 1_000_000);
69 0           $remain = $positive % 1_000_000;
70              
71 0           $out = 'milioni ' . num2swa_cardinal($mil);
72 0 0         $out .= ' ' . num2swa_cardinal($remain) if ($remain);
73             }
74              
75 0           return $out;
76 1     1   7 }
  1         1  
  1         22  
77              
78             # }}}
79              
80              
81             # {{{ num2swa_ordinal convert number to ordinal text
82              
83             sub num2swa_ordinal :Export {
84 0     0 1   my $number = shift;
85 0   0       my $prefix = shift // 'wa'; # noun-class prefix; default = wa (persons)
86              
87 0 0 0       croak 'You should specify a number from interval [1, 999_999_999]'
      0        
      0        
88             if !defined $number
89             || $number !~ m{\A\d+\z}xms
90             || $number < 1
91             || $number > 999_999_999;
92              
93             # Swahili ordinals: {noun-class-prefix} + "-a" + ordinal word.
94             # 1st through 5th and 8th have special stems; the rest use cardinals.
95 0           my %special = (
96             1 => 'kwanza',
97             2 => 'pili',
98             3 => 'tatu',
99             4 => 'nne',
100             5 => 'tano',
101             8 => 'nane',
102             );
103              
104 0   0       my $ordinal_word = $special{$number} // num2swa_cardinal($number);
105              
106 0           return $prefix . ' ' . $ordinal_word;
107 1     1   420 }
  1         1  
  1         4  
108              
109             # }}}
110              
111             # {{{ capabilities declare supported features
112              
113             sub capabilities {
114             return {
115 0     0 1   cardinal => 1,
116             ordinal => 1,
117             };
118             }
119              
120             # }}}
121             1;
122              
123             __END__