File Coverage

blib/lib/Valiemon.pm
Criterion Covered Total %
statement 53 53 100.0
branch 14 16 87.5
condition 5 9 55.5
subroutine 14 14 100.0
pod 0 5 0.0
total 86 97 88.6


line stmt bran cond sub pod time code
1             package Valiemon;
2 25     25   2282468 use 5.012;
  25         315  
3 25     25   131 use strict;
  25         46  
  25         514  
4 25     25   131 use warnings;
  25         48  
  25         652  
5 25     25   14780 use utf8;
  25         361  
  25         128  
6              
7 25     25   868 use Carp qw(croak);
  25         51  
  25         1179  
8 25     25   9400 use Valiemon::Primitives;
  25         72  
  25         778  
9 25     25   10040 use Valiemon::Context;
  25         67  
  25         868  
10 25     25   9724 use Valiemon::Attributes qw(attr);
  25         88  
  25         1559  
11              
12             use Class::Accessor::Lite (
13 25         195 ro => [qw(schema options pos schema_cache)],
14 25     25   183 );
  25         67  
15              
16             our $VERSION = "0.05";
17              
18             sub new {
19 588     588 0 1308132 my ($class, $schema, $options) = @_;
20              
21             # TODO should validate own schema
22 588 50       1512 if ($options->{validate_schema}) {}
23 588 50       1478 croak 'schema must be a hashref' unless ref $schema eq 'HASH';
24              
25 588         2703 return bless {
26             schema => $schema,
27             options => $options,
28             schema_cache => +{},
29             }, $class;
30             }
31              
32             sub validate {
33 1053     1053 0 419483 my ($self, $data, $context) = @_;
34 1053         2890 my $schema = $self->schema;
35              
36 1053   66     8689 $context //= Valiemon::Context->new($self, $schema);
37              
38 1053         1495 for my $key (keys %{$schema}) {
  1053         2771  
39 1314         3420 my $attr = attr($key);
40 1314 100       53319 if ($attr) {
41 1188         3915 my ($is_valid, $error) = $attr->is_valid($context, $schema, $data);
42 1130 100       6434 unless ($is_valid) {
43 380         1188 $error->set_detail(
44             expected => $schema,
45             actual => $data,
46             );
47 380         958 $context->push_error($error);
48 380         2385 next;
49             }
50             }
51             }
52              
53 995         2380 my $errors = $context->errors;
54 995 100       5355 my $is_valid = scalar @$errors ? 0 : 1;
55 995 100       4459 return wantarray ? ($is_valid, $errors->[0]) : $is_valid;
56             }
57              
58             sub prims {
59 977     977 0 5793 my ($self) = @_;
60 977   66     3979 return $self->{prims} //= Valiemon::Primitives->new(
61             $self->options
62             );
63             }
64              
65             sub ref_schema_cache {
66 84     84 0 158 my ($self, $ref, $schema) = @_;
67             return defined $schema
68             ? $self->schema_cache->{$ref} = $schema
69 84 100       305 : $self->{schema_cache}->{ref};
70             }
71              
72             sub resolve_ref {
73 58     58 0 395 my ($self, $ref) = @_;
74              
75             # TODO follow the standard referencing
76 58 100       398 unless ($ref =~ qr|^#/|) {
77 14         1535 croak 'This package support only single scope and `#/` referencing';
78             }
79              
80 44   33     141 return $self->ref_schema_cache($ref) || do {
81             my $paths = do {
82             my @p = split '/', $ref;
83             [ splice @p, 1 ]; # remove '#'
84             };
85             my $sub_schema = $self->schema;
86             {
87             eval { $sub_schema = $sub_schema->{$_} for @$paths };
88             croak sprintf 'referencing `%s` cause error', $ref if $@;
89             croak sprintf 'schema `%s` not found', $ref unless $sub_schema;
90             }
91             $self->ref_schema_cache($ref, $sub_schema); # caching
92             $sub_schema;
93             };
94             }
95              
96              
97             1;
98              
99             __END__