File Coverage

blib/lib/DTL/Fast/Filter/Dictsort.pm
Criterion Covered Total %
statement 33 34 97.0
branch 5 8 62.5
condition 3 3 100.0
subroutine 9 9 100.0
pod 0 3 0.0
total 50 57 87.7


line stmt bran cond sub pod time code
1             package DTL::Fast::Filter::Dictsort;
2 3     3   983 use strict;
  3         7  
  3         65  
3 3     3   12 use utf8;
  3         6  
  3         11  
4 3     3   70 use warnings FATAL => 'all';
  3         5  
  3         75  
5 3     3   12 use parent 'DTL::Fast::Filter';
  3         5  
  3         12  
6              
7             $DTL::Fast::FILTER_HANDLERS{dictsort} = __PACKAGE__;
8              
9 3     3   144 use Scalar::Util qw(looks_like_number);
  3         6  
  3         105  
10 3     3   349 use locale;
  3         437  
  3         15  
11              
12             #@Override
13             sub parse_parameters
14             {
15 4     4 0 7 my $self = shift;
16             die $self->get_parse_error("no sorting key specified")
17 4 50       5 if (not scalar @{$self->{parameter}});
  4         13  
18 4         14 $self->{key} = [ split /\./, $self->{parameter}->[0]->render() ]; # do we need to backup strings here ?
19 4         14 return $self;
20             }
21              
22             #@Override
23             sub filter
24             {
25 4     4 0 9 my ($self, $filter_manager, $value, $context) = @_;
26              
27 4 50       12 die $self->get_render_error("dictsort works only with array of hashes")
28             if (ref $value ne 'ARRAY');
29              
30             return [ (
31             sort{
32 4         16 $self->sort_function(
33             $context->traverse($a, $self->{key}, $self)
34 10         34 , $context->traverse($b, $self->{key}, $self)
35             )
36             } @$value
37             ) ];
38             }
39              
40             sub sort_function
41             {
42 10     10 0 22 my ($self, $val1, $val2) = @_;
43 10         12 my $result;
44              
45 10 100 100     64 if (looks_like_number($val1) and looks_like_number($val2))
    50          
46             {
47 5         10 $result = ($val1 <=> $val2);
48             }
49             elsif (UNIVERSAL::can($val1, 'compare'))
50             {
51 0         0 $result = $val1->compare($val2);
52             }
53             else
54             {
55 5         9 $result = ($val1 cmp $val2);
56             }
57              
58 10         33 return $result;
59             }
60              
61             1;