File Coverage

blib/lib/Avro/Protocol.pm
Criterion Covered Total %
statement 63 66 95.4
branch 3 6 50.0
condition 4 9 44.4
subroutine 17 19 89.4
pod 0 5 0.0
total 87 105 82.8


line stmt bran cond sub pod time code
1             # Licensed to the Apache Software Foundation (ASF) under one
2             # or more contributor license agreements. See the NOTICE file
3             # distributed with this work for additional information
4             # regarding copyright ownership. The ASF licenses this file
5             # to you under the Apache License, Version 2.0 (the
6             # "License"); you may not use this file except in compliance
7             # with the License. You may obtain a copy of the License at
8             #
9             # https://www.apache.org/licenses/LICENSE-2.0
10             #
11             # Unless required by applicable law or agreed to in writing,
12             # software distributed under the License is distributed on an
13             # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14             # KIND, either express or implied. See the License for the
15             # specific language governing permissions and limitations
16             # under the License.
17              
18             package Avro::Protocol;
19 1     1   751 use strict;
  1         3  
  1         28  
20 1     1   5 use warnings;
  1         2  
  1         22  
21              
22 1     1   6 use Carp;
  1         2  
  1         52  
23 1     1   663 use JSON::XS();
  1         3045  
  1         23  
24 1     1   520 use Try::Tiny;
  1         2165  
  1         57  
25 1     1   427 use Avro::Protocol::Message;
  1         3  
  1         6  
26 1     1   28 use Avro::Schema;
  1         2  
  1         18  
27 1     1   4 use Error;
  1         2  
  1         5  
28 1         4 use Object::Tiny qw{
29             name
30             namespace
31             doc
32             types
33             messages
34 1     1   51 };
  1         2  
35              
36             our $VERSION = '1.11.2';
37              
38             my $json = JSON::XS->new->allow_nonref;
39              
40             sub parse {
41 1     1 0 1024 my $class = shift;
42 1 50       3 my $enc_proto = shift
43             or throw Avro::Protocol::Error::Parse("protocol cannot be empty");
44              
45             my $struct = try {
46 1     1   99 $json->decode($enc_proto);
47             }
48             catch {
49 0     0   0 throw Avro::Protocol::Error::Parse(
50             "Cannot parse json string: $_"
51             );
52 1         8 };
53 1         21 return $class->from_struct($struct);
54             }
55              
56             sub from_struct {
57 1     1 0 2 my $class = shift;
58 1   50     5 my $struct = shift || {};
59 1         2 my $name = $struct->{protocol};
60 1 50 33     23 unless (defined $name or length $name) {
61 0         0 throw Avro::Protocol::Error::Parse("protocol name is required");
62             }
63              
64 1         5 my $types = $class->parse_types($struct->{types});
65              
66             my $messages = $struct->{messages} ?
67 1 50       15 $class->parse_messages($struct->{messages}, $types) : undef;
68              
69             my $protocol = $class->SUPER::new(
70             name => $name,
71             namespace => $struct->{namespace},
72             doc => $struct->{doc},
73 1         13 types => $types,
74             messages => $messages,
75             );
76 1         14 return $protocol;
77             }
78              
79             sub parse_types {
80 1     1 0 2 my $class = shift;
81 1   50     3 my $types = shift || [];
82              
83 1         2 my %types;
84 1         2 my $names = {};
85 1         2 for (@$types) {
86             try {
87 2     2   139 my $schema = Avro::Schema->parse_struct($_, $names);
88 2         12 $types{ $schema->fullname } = $schema;
89             }
90             catch {
91 0     0   0 throw Avro::Protocol::Error::Parse("errors in parsing types: $_");
92 2         34 };
93             }
94 1         17 return \%types;
95             }
96              
97             sub parse_messages {
98 1     1 0 4 my $class = shift;
99 1   50     4 my $messages = shift || {};
100 1         1 my $types = shift;
101 1         30 my $m = {};
102 1         7 for my $name (keys %$messages) {
103 1         5 $m->{$name} = Avro::Protocol::Message->new($messages->{$name}, $types);
104             }
105 1         17 return $m;
106             }
107              
108             sub fullname {
109 1     1 0 961 my $protocol = shift;
110 1         3 return join ".", grep { $_ } map { $protocol->$_ } qw{ namespace name };
  2         15  
  2         46  
111             }
112              
113             package Avro::Protocol::Error::Parse;
114 1     1   833 use parent 'Error::Simple';
  1         2  
  1         5  
115              
116             1;