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)) {
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;