File Coverage

blib/lib/IO/Prompt/I18N.pm
Criterion Covered Total %
statement 11 74 14.8
branch 0 44 0.0
condition 0 38 0.0
subroutine 4 6 66.6
pod 2 2 100.0
total 17 164 10.3


line stmt bran cond sub pod time code
1             package IO::Prompt::I18N;
2              
3 1     1   335548 use 5.010001;
  1         4  
4 1     1   6 use strict;
  1         2  
  1         34  
5 1     1   5 use warnings;
  1         3  
  1         79  
6              
7 1     1   6 use Exporter qw(import);
  1         3  
  1         1203  
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2023-11-20'; # DATE
11             our $DIST = 'IO-Prompt-I18N'; # DIST
12             our $VERSION = '0.81'; # VERSION
13              
14             our @EXPORT_OK = qw(prompt confirm);
15              
16             sub prompt {
17 0     0 1   my ($text, $opts) = @_;
18              
19 0   0       $text //= "Enter value";
20 0   0       $opts //= {};
21              
22 0           my $answer;
23              
24             my $default;
25 0 0         $default = ${$opts->{var}} if $opts->{var};
  0            
26 0 0         $default = $opts->{default} if defined($opts->{default});
27              
28 0           while (1) {
29             # prompt
30 0           print $text;
31 0 0 0       print " ($default)" if defined($default) && $opts->{show_default}//1;
      0        
32 0 0         print ":" unless $text =~ /[:?]\s*$/;
33 0           print " ";
34              
35             # get input
36 0           $answer = ;
37 0 0         if (!defined($answer)) {
38 0           print "\n";
39 0           $answer = "";
40             }
41 0           chomp($answer);
42              
43             # check+process answer
44 0 0         if (defined($default)) {
45 0 0         $answer = $default if !length($answer);
46             }
47 0           my $success = 1;
48 0 0         if ($opts->{required}) {
49 0 0         $success = 0 if !length($answer);
50             }
51 0 0         if ($opts->{regex}) {
52 0 0         $success = 0 if $answer !~ /$opts->{regex}/;
53             }
54 0 0         last if $success;
55             }
56 0 0         ${$opts->{var}} = $answer if $opts->{var};
  0            
57 0           $answer;
58             }
59              
60             sub confirm {
61 0     0 1   my ($text, $opts) = @_;
62              
63 0   0       $opts //= {};
64              
65 0           state $supported_langs = {
66             en => {yes_words=>[qw/y yes/], no_words=>[qw/n no/] , text=>'Confirm'},
67             fr => {yes_words=>[qw/o oui/], no_words=>[qw/n non/] , text=>'Confirmer'},
68             id => {yes_words=>[qw/y ya/] , no_words=>[qw/t tidak/], text=>'Konfirmasi'},
69             };
70              
71 0   0       $opts->{lang} //= do {
72 0 0 0       if ($ENV{LANG} && $ENV{LANG} =~ /^([a-z]{2})/ &&
    0 0        
      0        
      0        
73             $supported_langs->{$1}) {
74 0           $1;
75             } elsif ($ENV{LANGUAGE} && $ENV{LANGUAGE} =~ /^([a-z]{2})/ &&
76             $supported_langs->{$1}) {
77 0           $1;
78             } else {
79 0           'en';
80             }
81             };
82              
83             my $lang = $supported_langs->{$opts->{lang}}
84 0 0         or die "Unknown language '$opts->{lang}'";
85 0   0       $text //= $lang->{text};
86 0   0       $opts->{yes_words} //= $lang->{yes_words};
87 0   0       $opts->{no_words} //= $lang->{no_words};
88              
89 0           my $default;
90 0 0         if (defined $opts->{default}) {
91 0 0         if ($opts->{default}) {
92 0           $default = $opts->{yes_words}[0];
93             } else {
94 0           $default = $opts->{no_words}[0];
95             }
96             }
97              
98 0           my $suffix;
99 0           my $show_default = 1;
100 0 0         unless ($text =~ /[?]/) {
101             $text .=
102             join("",
103             " (",
104             join("/",
105 0 0         (map {$opts->{default} ? uc($_) : lc($_)}
106 0           @{ $opts->{yes_words} }),
107             (map {defined($opts->{default}) && !$opts->{default} ?
108 0 0 0       uc($_) : lc($_)}
109 0           @{ $opts->{no_words} }),
  0            
110             ),
111             ")?",
112             );
113 0           $show_default = 0; # because we already indicate which using uppercase
114             }
115              
116 0           my $re = join("|", map {quotemeta}
117 0           (@{$opts->{yes_words}}, @{$opts->{no_words}}));
  0            
  0            
118 0           $re = qr/\A($re)\z/i;
119              
120 0           my $answer = prompt($text, {
121             required => 1,
122             regex => $re,
123             show_default => $show_default,
124             default => $default,
125             });
126 0 0         (grep {$_ eq $answer} @{$opts->{yes_words}}) ? 1:0;
  0            
  0            
127             }
128              
129             1;
130             # ABSTRACT: Prompt user question, with some options (including I18N)
131              
132             __END__