File Coverage

blib/lib/App/Config/Chronicle/Attribute.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package App::Config::Chronicle::Attribute;
2             $App::Config::Chronicle::Attribute::VERSION = '0.05';
3 2     2   85913 use Moose;
  2         290370  
  2         10  
4             extends 'App::Config::Chronicle::Node';
5 2     2   9579 use namespace::autoclean;
  2         10674  
  2         6  
6 2     2   1241 use JSON::XS qw( decode_json );
  2         7341  
  2         96  
7              
8 2     2   290 use MooseX::Types -declare => ['LongStr'];
  0            
  0            
9             use Moose::Util::TypeConstraints;
10             use Try::Tiny;
11              
12             subtype 'LongStr', as 'Str';
13              
14             =head1 NAME
15              
16             App::Config::Chronicle::Attribute
17              
18             =head1 VERSION
19              
20             version 0.05
21              
22             =head1 ATTRIBUTES
23              
24             =cut
25              
26             has 'version' => (
27             is => 'rw',
28             );
29              
30             sub _check_type {
31             my ($self, $value) = @_;
32             my $def = $self->{definition};
33             $self->{_json_string} //= $def->{isa} eq 'json_string' ? 1 : 0;
34             if ($self->{_json_string}) {
35             try { $value = decode_json($value) } catch { die "Couldn't decode JSON attribute $value: $_" };
36             } else {
37             $self->{_type_constraint} //= find_type_constraint($def->{isa});
38             unless ($self->{_type_constraint}) {
39             die "Couldn't find type constraint for " . $def->{isa} . " for " . $self->name;
40             }
41             $self->{_type_constraint}->check($value) or die $self->name . " expecting a value of type " . $def->{isa};
42             }
43             return;
44             }
45              
46             =head2 value
47              
48             =cut
49              
50             sub value {
51             my ($self, $value) = @_;
52              
53             if (defined $value) {
54             $self->_check_type($value);
55             $self->{_value} = $value;
56             $self->_set_value($value);
57             $self->version($self->data_set->{version}); #Avoids building after set unless version changed.
58             } else {
59             if (not $self->version or $self->version ne $self->data_set->{version}) {
60             my $val = $self->_build_value;
61             if (defined $val) {
62             $self->value($val);
63             $self->version($self->data_set->{version});
64             }
65             }
66             }
67              
68             return $self->{_value};
69             }
70              
71             =head2 build
72              
73             =cut
74              
75             sub build {
76             my $self = shift;
77             my $default = $self->definition->{default};
78             $self->_check_type($default);
79             $self->{_value} = $default;
80             return $self;
81             }
82              
83             sub _build_value {
84             my $self = shift;
85             my $value;
86             $value //= $self->data_set->{app_config}->get($self->path) if ($self->data_set->{app_config});
87             $value //= $self->definition->{default} if ($self->definition);
88              
89             return $value;
90             }
91              
92             sub _set_value {
93             return;
94             }
95              
96             __PACKAGE__->meta->make_immutable;
97              
98             1;