a6e613c9af8ef07a890a196bb2c45485a32d95ed
[scpubgit/Clifton.git] / lib / App / Clifton / Set.pm
1 package App::Clifton::Set;
2
3 use Scalar::Util qw(blessed);
4 use Moo::Role;
5
6 requires '_set_of_class';
7 requires '_set_over';
8
9 has _set => (is => 'ro', default => sub { {} });
10
11 sub add {
12   my ($self, $spec) = @_;
13   $self->_set->{$self->_spec_to_key($spec)} = $self->_spec_to_object($spec);
14 }
15
16 sub get {
17   my ($self, $spec) = @_;
18   $self->_set->{$self->_spec_to_key($spec)};
19 }
20
21 sub remove {
22   my ($self, $spec) = @_;
23   delete $self->_set->{$self->_spec_to_key($spec)};
24 }
25
26 sub flatten {
27   my ($self) = @_;
28   my $set = $self->_set;
29   map $set->{$_}, sort keys %$set;
30 }
31
32 sub _spec_to_object {
33   my ($self, $spec) = @_;
34   if (blessed($spec) && $spec->isa($self->_set_of_class)) {
35     $spec;
36   } else {
37     $self->_new_member($self->_spec_to_constructor_args($spec));
38   }
39 }
40
41 sub _new_member {
42   my ($self, $args) = @_;
43   $self->_set_of_class->new($args);
44 }
45
46 sub _spec_to_constructor_args {
47   my ($self, $spec) = @_;
48   $spec;
49 }
50
51 sub _spec_to_key {
52   my ($self, $spec) = @_;
53   my $key = $self->_set_over;
54   die "key ${key} is required" unless $spec->{$key};
55   $spec->{$key};
56 }
57
58 1;