File Coverage

blib/lib/Tree/Serial.pm
Criterion Covered Total %
statement 8 72 11.1
branch 0 26 0.0
condition 0 6 0.0
subroutine 3 13 23.0
pod 2 3 66.6
total 13 120 10.8


line stmt bran cond sub pod time code
1             package Tree::Serial;
2              
3 1     1   78954 use warnings;
  1         2  
  1         24  
4 1     1   8 use v5.12;
  1         2  
5              
6 1     1   4 use List::Util qw(min reduce sum zip);
  1         1  
  1         787  
7              
8             our $VERSION=0.20;
9              
10             sub new {
11 0     0 0   my ($class,$data) = @_;
12 0           my $self = {};
13 0           bless $self, $class;
14 0           $self->_init($data);
15 0           return $self;
16             }
17              
18             sub _init {
19 0     0     my ($self,$data) = @_;
20             my %data = (
21             separator => '.',
22             degree => 2,
23             traversal => 0,
24 0 0         (defined $data) ? (%{$data}) : (),
  0            
25             );
26 0 0         (exists $data{showMissing}) && do {$self->{showMissing} = $data{showMissing}};
  0            
27 0           @{$self}{qw(separator degree traversal)} = @data{qw(separator degree traversal)};
  0            
28             }
29              
30             sub _eatWhileNot {
31 0     0     my ($pred,$acc,$el) = @_;
32 0           my @larger = (@{$acc->[1]}, $el);
  0            
33 0 0         return ($pred->(\@larger)) ? ([[@{$acc->[0]}, \@larger],[]]) : ([$acc->[0], \@larger]);
  0            
34             }
35              
36             sub _chunkBy {
37 0     0     my ($pred,$aref) = @_;
38 0     0     my $reduction = reduce { _eatWhileNot($pred, $a, $b) } [[],[]], @{$aref};
  0            
  0            
39 0           return $reduction->[0];
40             }
41              
42             sub _isKAry {
43 0     0     my ($separator,$degree,$aref) = @_;
44 0 0         return ((sum map { ($_ eq $separator) ? (-1) : ($degree-1) } @{$aref}) == -1);
  0            
  0            
45             }
46              
47             sub _chunkKAry {
48 0     0     my ($separator,$degree,$aref) = @_;
49 0     0     my $pred = sub { _isKAry($separator,$degree,$_[0]) };
  0            
50 0           return _chunkBy($pred,$aref);
51             }
52              
53             sub strs2hash {
54 0     0 1   my ($self, $aref) = @_;
55 0 0         (! scalar @{$aref}) && return {};
  0            
56 0 0         ($aref->[0] eq $self->{separator}) && do {
57 0 0 0       (exists $self->{showMissing} && defined $self->{showMissing}) && return {name => $self->{showMissing}};
58 0 0         (exists $self->{showMissing}) && return {};
59 0           return;
60             };
61 0           my @rest = @{$aref}[1..scalar @{$aref}-1];
  0            
  0            
62 0           my @chunks = @{_chunkKAry($self->{separator}, $self->{degree}, \@rest)};
  0            
63 0 0         (! exists $self->{showMissing}) && do {@chunks = grep {$_->[0] ne $self->{separator}} @chunks};
  0            
  0            
64             my %h = (
65             name => $aref->[0],
66 0           map {$_->[0] => strs2hash($self,$_->[1])} zip [0..$#chunks], \@chunks,
  0            
67             );
68 0           return \%h;
69             }
70              
71             sub strs2lol {
72 0     0 1   my ($self, $aref) = @_;
73 0 0         (! scalar @{$aref}) && return [];
  0            
74 0 0         ($aref->[0] eq $self->{separator}) && do {
75 0 0 0       (exists $self->{showMissing} && defined $self->{showMissing}) && return [$self->{showMissing}];
76 0 0         (exists $self->{showMissing}) && return [];
77 0           return;
78             };
79 0           my @rest = @{$aref}[1..scalar @{$aref}-1];
  0            
  0            
80 0           my $chunks = _chunkKAry($self->{separator}, $self->{degree}, \@rest);
81 0           my @others = map {strs2lol($self,$_)} @{$chunks};
  0            
  0            
82 0           splice(@others,min(scalar @others, $self->{traversal}),0,$aref->[0]);
83 0           return \@others;
84             }
85              
86             1;
87              
88             __END__