summaryrefslogtreecommitdiff
path: root/lib/Data/MultiValued/AttributeTrait/TagsAndRanges.pm
blob: 10a1a94610f95430b8c941eac3f7292365b7398c (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
88
89
90
91
92
93
94
95
96
97
98
99
package Data::MultiValued::AttributeTrait::TagsAndRanges; 
use Moose::Role;
use namespace::autoclean;
use Data::MultiValued::TagsAndRanges;
with 'Data::MultiValued::AttributeTrait';
 
# ABSTRACT: attribute traits for attributes holding tagged and ranged values 
 
=head1 SYNOPSIS
 
  package My::Class;
  use Moose;
  use Data::MultiValued::AttributeTrait::TagsAndRanges;
 
  has stuff => (
    is => 'rw',
    isa => 'Int',
    traits => ['MultiValued::TagsAndRanges'],
    predicate => 'has_stuff',
    multi_accessor => 'stuff_tagged',
    multi_predicate => 'has_stuff_tagged',
  );
 
=head1 DESCRIPTION
 
This role consumes L<Data::MultiValued::AttributeTrait> and
specialises it to use L<Data::MultiValued::TagsAndRanges> as multi-value
storage:
 
=head2 C<multivalue_storage_class>
 
Returns C<'Data::MultiValued::TagsAndRanges'>.
 
=head2 C<opts_to_pass_set>
 
Returns C<('tag', 'from', 'to')>.
 
=head2 C<opts_to_pass_get>
 
Returns C<('tag', 'at')>.
 
=head2 C<all_tags>
 
  my @tags = $obj->meta->get_attribute('my_attr')->all_tags($obj);
 
Returns a list of all values for which C<<
$obj->has_my_attr_multi({tag=>$tag}) >> would return true.
 
=head2 C<all_tags_and_ranges>
 
  my @tags_and_ranges = $obj->meta->get_attribute('my_attr')
     ->all_tags_and_ranges($obj);
 
Returns a list of 2-element arrayrefs. The first element of each
arrayref is a tag (possibly C<undef>), the second element is an
arrayref of 2-element arrayrefs, each arrayref describing the extremes
of a range. Something like:
 
   [
    [ 'x', [ [undef,10], [10,20], [20,undef] ] ],
    [ undef, [ [undef,undef] ] ],
   ],
 
=cut
 
sub multivalue_storage_class 'Data::MultiValued::TagsAndRanges' };
sub opts_to_pass_set qw(from to tag) }
sub opts_to_pass_get qw(at tag) }
 
require Data::MultiValued::AttributeTrait::Tags;
 
sub all_tags {
    my ($self,$instance) = @_;
    return $self->Data::MultiValued::AttributeTrait::Tags::all_tags($instance);
}
 
sub all_tags_and_ranges {
    my ($self,$instance) = @_;
 
    my $storage = $self->get_full_storage($instance);
    return unless $storage;
 
    my @tags = $self->all_tags($instance);
 
    my @tags_and_ranges;
    for my $tag (@tags) {
        my @these_ranges = $storage->_storage
            ->get({tag=>$tag})->all_ranges;
        push @tags_and_ranges,[$tag, \@these_ranges];
    }
 
    return @tags_and_ranges;
}
 
package Moose::Meta::Attribute::Custom::Trait::MultiValued::TagsAndRanges;{ 
sub register_implementation 'Data::MultiValued::AttributeTrait::TagsAndRanges' }
}
 
1;