File Coverage

blib/lib/App/yajg/Output.pm
Criterion Covered Total %
statement 36 69 52.1
branch 5 28 17.8
condition 3 18 16.6
subroutine 10 16 62.5
pod 0 8 0.0
total 54 139 38.8


line stmt bran cond sub pod time code
1             package App::yajg::Output;
2              
3 1     1   352 use 5.014000;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         14  
5 1     1   3 use warnings;
  1         0  
  1         17  
6 1     1   2 use utf8;
  1         1  
  1         3  
7              
8 1     1   355 use App::yajg;
  1         1  
  1         38  
9 1     1   4 use Data::Dumper qw();
  1         1  
  1         216  
10              
11             # Class methods
12 3     3 0 4568 sub new { bless {}, shift }
13              
14             {
15             my $can_hl = eval {
16             # FIXME: probably will not work if not unix os
17             qx(which highlight 2>/dev/null) and $? == 0
18             };
19 0     0 0 0 sub can_highlight {$can_hl}
20             }
21              
22 0     0 0 0 sub lang {...} # lang for highlight
23 0     0 0 0 sub need_change_depth {1} # need to change max depth via Data::Dumper
24              
25             sub highlight {
26 0     0 0 0 my ($class, $string) = @_;
27 0 0       0 $class = ref $class if ref $class;
28              
29 0 0 0     0 return $string unless $class->can_highlight and length $string;
30              
31             # IPC::Open2 hangs on big data so we will do like this
32 0         0 my $pid = open(my $hl_out, '-|');
33 0 0       0 if (not defined $pid) {
34 0         0 warn "highlight failed: $!\n";
35 0         0 return $string;
36             }
37 0         0 my $utf8 = utf8::is_utf8($string);
38              
39 0 0       0 unless ($pid) {
40 0 0       0 open(my $hl_in, '|-', 'highlight', '-O', 'ansi', '-S', $class->lang)
41             or die "$!\n";
42 0 0       0 utf8::encode($string) if utf8::is_utf8($string);
43 0         0 print $hl_in $string;
44 0         0 close $hl_in;
45 0         0 exit 0;
46             }
47              
48 0         0 local $/;
49 0         0 my $highlighted = <$hl_out>;
50 0         0 close $hl_out; # may be waitpid($pid, 0); ??
51 0 0       0 return $string unless $? == 0;
52 0 0 0     0 utf8::decode($highlighted) if $utf8 and not utf8::is_utf8($highlighted);
53              
54 0   0     0 return $highlighted || $string;
55             }
56              
57             # Object methods
58              
59             # Getters/Setters
60             for my $method (qw(data color minimal max_depth sort_keys escapes)) {
61 1     1   3 no strict 'refs';
  1         1  
  1         255  
62             *{ __PACKAGE__ . "::$method" } = sub {
63 72     72   8287 my $self = shift;
64 72 100       310 return $self->{ '_' . $method } unless @_;
65 24         44 $self->{ '_' . $method } = shift;
66 24         48 return $self;
67             };
68             }
69              
70             sub change_depth {
71 5     5 0 8 my $self = shift;
72 5         7 my $class = ref $self;
73 5 100 66     14 return $self unless $class->need_change_depth and $self->max_depth;
74 4         13 local $SIG{__WARN__} = \&App::yajg::warn_without_line;
75             # TODO: fails to restore true, false when depth and boolean at same level
76             # but we can restore 1 or 0 or maybe 'true' 'false' (depend on version)
77 4         4 my $VAR1;
78 4         5 my $code = Data::Dumper->new([$self->data])->Maxdepth($self->max_depth)->Dump();
79             # 2x eval to prevent problems with max depth and boolean type
80             # Deepcopy has no effect when depth 1 and true/false =(
81 4         472 eval $code; eval $code;
  4         213  
82 4 50 33     28 if ($@ or not defined $VAR1) {
83 0         0 warn "max_depth failed: $@";
84             }
85             else {
86 4         8 $self->data($VAR1);
87             }
88 4         16 return $self;
89             }
90              
91             sub as_string {
92             ...
93 0     0 0   }
94              
95             sub print {
96 0     0 0   my $self = shift;
97 0           my $class = ref $self;
98 0           my $out = $self->change_depth->as_string;
99 0 0 0       $out = $class->highlight($out) if $self->color and $class->can_highlight;
100 0 0         utf8::encode($out) if utf8::is_utf8($out);
101 0 0         $out .= "\n" unless $out =~ m/\n\z/;
102 0           print $out;
103 0           return $self;
104             }
105              
106             1;