summaryrefslogtreecommitdiff
path: root/lib/WebService/ForecastIo/DataBlock.pm
blob: 1994fa83afada0648d6fe20b89529db5c96f3d50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package WebService::ForecastIo::DataBlock; 
use Moo;
use namespace::autoclean;
use Types::Standard -all;
use WebService::ForecastIo::Types -all;
use WebService::ForecastIo::DataSpan;
 
has [qw(summary icon)] => (
    is => 'ro',
    isa => Str,
);
 
has data => (
    is => 'ro',
    isa => DataPointArray,
    coerce => DataPointArray->coercion,
);
sub data_points { @{$_[0]->data} }
 
sub spans_by_string {
    my ($self,$field) = @_;
 
    $self->_spans(
        $field,
        sub { $_[0] eq $_[1] }
    );
}
 
sub spans_by_number {
    my ($self,$field,$tolerance) = @_;
 
    $self->_spans(
        $field,
        sub { abs($_[0] - $_[1]) <= $tolerance }
    );
}
 
sub slice {
    my ($self,%opts) = @_;
 
    my $from = $opts{from// 0-'Inf';
    my $to = $opts{to// 0+'Inf';
 
    return ref($self)->new({
        summary => $self->summary,
        icon => $self->icon,
        data => [
            grep { $_->time >= $from && $_->time <= $to }
                $self->data_points
            ],
    });
}
 
sub _spans {
    my ($self,$field,$comp) = @_;
 
    my $out;
    for my $dp ($self->data_points) {
        next unless $dp->time;
        my $v = $dp->$field;
        if (!$out) {
            $out = [ WebService::ForecastIo::DataSpan->new({
                start_time => $dp->time,
                stop_time => $dp->time,
                value => $v,
            }) ];
        }
        else {
            my $prev = $out->[-1]->value;
            $out->[-1]->_set_stop_time($dp->time);
            if (not $comp->($prev,$v)) { # new span 
                push @$out, WebService::ForecastIo::DataSpan->new({
                    start_time => $dp->time,
                    stop_time => $dp->time,
                    value => $v,
                });
            }
        }
    }
    if (@$out) {
        $out->[-1]->_set_stop_time($self->data->[-1]->time);
    }
 
    return $out;
}
 
1;