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   630 use strict;
  1         2  
  1         22  
20 1     1   3 use warnings;
  1         2  
  1         17  
21              
22 1     1   4 use Carp;
  1         1  
  1         39  
23 1     1   593 use JSON::XS();
  1         2453  
  1         18  
24 1     1   488 use Try::Tiny;
  1         1698  
  1         43  
25 1     1   339 use Avro::Protocol::Message;
  1         2  
  1         5  
26 1     1   23 use Avro::Schema;
  1         2  
  1         14  
27 1     1   4 use Error;
  1         1  
  1         5  
28 1         2 use Object::Tiny qw{
29             name
30             namespace
31             doc
32             types
33             messages
34 1     1   41 };
  1         2  
35              
36             our $VERSION = '1.11.3';
37              
38             my $json = JSON::XS->new->allow_nonref;
39              
40             sub parse {
41 1     1 0 924 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   85 $json->decode($enc_proto);
47             }
48             catch {
49 0     0   0 throw Avro::Protocol::Error::Parse(
50             "Cannot parse json string: $_"
51             );
52 1         6 };
53 1         16 return $class->from_struct($struct);
54             }
55              
56             sub from_struct {
57 1     1 0 1 my $class = shift;
58 1   50     3 my $struct = shift || {};
59 1         1 my $name = $struct->{protocol};
60 1 50 33     11 unless (defined $name or length $name) {
61 0         0 throw Avro::Protocol::Error::Parse("protocol name is required");
62             }
63              
64 1         4 my $types = $class->parse_types($struct->{types});
65              
66             my $messages = $struct->{messages} ?
67 1 50       3 $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         10 types => $types,
74             messages => $messages,
75             );
76 1         10 return $protocol;
77             }
78              
79             sub parse_types {
80 1     1 0 1 my $class = shift;
81 1   50     3 my $types = shift || [];
82              
83 1         9 my %types;
84 1         2 my $names = {};
85 1         2 for (@$types) {
86             try {
87 2     2   103 my $schema = Avro::Schema->parse_struct($_, $names);
88 2         5 $types{ $schema->fullname } = $schema;
89             }
90             catch {
91 0     0   0 throw Avro::Protocol::Error::Parse("errors in parsing types: $_");
92 2         21 };
93             }
94 1         13 return \%types;
95             }
96              
97             sub parse_messages {
98 1     1 0 2 my $class = shift;
99 1   50     2 my $messages = shift || {};
100 1         1 my $types = shift;
101 1         1 my $m = {};
102 1         3 for my $name (keys %$messages) {
103 1         2 $m->{$name} = Avro::Protocol::Message->new($messages->{$name}, $types);
104             }
105 1         8 return $m;
106             }
107              
108             sub fullname {
109 1     1 0 722 my $protocol = shift;
110 1         2 return join ".", grep { $_ } map { $protocol->$_ } qw{ namespace name };
  2         18  
  2         39  
111             }
112              
113             package Avro::Protocol::Error::Parse;
114 1     1   678 use parent 'Error::Simple';
  1         1  
  1         5  
115              
116             1;