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   320872 use 5.012;
  25         62  
3 25     25   84 use strict;
  25         28  
  25         412  
4 25     25   82 use warnings;
  25         672  
  25         539  
5 25     25   11698 use utf8;
  25         188  
  25         84  
6              
7 25     25   681 use Carp qw(croak);
  25         28  
  25         1201  
8 25     25   7579 use Valiemon::Primitives;
  25         42  
  25         575  
9 25     25   7566 use Valiemon::Context;
  25         38  
  25         643  
10 25     25   7181 use Valiemon::Attributes qw(attr);
  25         43  
  25         1266  
11              
12             use Class::Accessor::Lite (
13 25         185 ro => [qw(schema options pos schema_cache)],
14 25     25   98 );
  25         23  
15              
16             our $VERSION = "0.04";
17              
18             sub new {
19 584     584 0 296594 my ($class, $schema, $options) = @_;
20              
21             # TODO should validate own schema
22 584 50       1110 if ($options->{validate_schema}) {}
23 584 50       1049 croak 'schema must be a hashref' unless ref $schema eq 'HASH';
24              
25 584         1927 return bless {
26             schema => $schema,
27             options => $options,
28             schema_cache => +{},
29             }, $class;
30             }
31              
32             sub validate {
33 1047     1047 0 148556 my ($self, $data, $context) = @_;
34 1047         1968 my $schema = $self->schema;
35              
36 1047   66     5993 $context //= Valiemon::Context->new($self, $schema);
37              
38 1047         896 for my $key (keys %{$schema}) {
  1047         2094  
39 1303         2362 my $attr = attr($key);
40 1302 100       33808 if ($attr) {
41 1175         2827 my ($is_valid, $error) = $attr->is_valid($context, $schema, $data);
42 1118 100       4536 unless ($is_valid) {
43 378         728 $error->set_detail(
44             expected => $schema,
45             actual => $data,
46             );
47 378         629 $context->push_error($error);
48 378         1563 next;
49             }
50             }
51             }
52              
53 989         1664 my $errors = $context->errors;
54 989 100       3227 my $is_valid = scalar @$errors ? 0 : 1;
55 989 100       3075 return wantarray ? ($is_valid, $errors->[0]) : $is_valid;
56             }
57              
58             sub prims {
59 896     896 0 2913 my ($self) = @_;
60 896   66     2747 return $self->{prims} //= Valiemon::Primitives->new(
61             $self->options
62             );
63             }
64              
65             sub ref_schema_cache {
66 87     87 0 81 my ($self, $ref, $schema) = @_;
67             return defined $schema
68             ? $self->schema_cache->{$ref} = $schema
69 87 100       289 : $self->{schema_cache}->{ref};
70             }
71              
72             sub resolve_ref {
73 59     59 0 236 my ($self, $ref) = @_;
74              
75             # TODO follow the standard referencing
76 59 100       313 unless ($ref =~ qr|^#/|) {
77 14         1293 croak 'This package support only single scope and `#/` referencing';
78             }
79              
80 45   33     85 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__