File Coverage

blib/lib/Wikibase/Datatype/Struct/Utils.pm
Criterion Covered Total %
statement 58 60 96.6
branch 18 20 90.0
condition 3 3 100.0
subroutine 9 9 100.0
pod 2 2 100.0
total 90 94 95.7


line stmt bran cond sub pod time code
1             package Wikibase::Datatype::Struct::Utils;
2              
3 34     34   369459 use base qw(Exporter);
  34         123  
  34         3690  
4 34     34   227 use strict;
  34         77  
  34         737  
5 34     34   179 use warnings;
  34         66  
  34         984  
6              
7 34     34   1352 use English;
  34         8074  
  34         274  
8 34     34   18129 use Error::Pure qw(err);
  34         16230  
  34         1507  
9 34     34   4506 use List::MoreUtils qw(none);
  34         87208  
  34         302  
10              
11             Readonly::Array our @EXPORT_OK => qw(obj_array_ref2struct struct2snaks_array_ref);
12              
13             our $VERSION = 0.08;
14              
15             sub obj_array_ref2struct {
16 11     11 1 6862 my ($snaks_ar, $key, $base_uri, $snak_obj, $struct_snak_obj) = @_;
17              
18 11 100       38 if (! defined $snak_obj) {
19 10         23 $snak_obj = 'Wikibase::Datatype::Snak';
20             }
21 11 100       48 if (! defined $struct_snak_obj) {
22 10         18 $struct_snak_obj = 'Wikibase::Datatype::Struct::Snak';
23             }
24 11         866 eval "require $struct_snak_obj";
25 11 50       66 if ($EVAL_ERROR) {
26 0         0 err "Cannot load '$struct_snak_obj'";
27             }
28              
29 11 100       50 if (! defined $base_uri) {
30 1         5 err 'Base URI is required.';
31             }
32              
33 10         53 my $snaks_hr = {
34             $key.'-order' => [],
35             $key => {},
36             };
37 10         23 foreach my $snak_o (@{$snaks_ar}) {
  10         32  
38 19 100       92 if (! $snak_o->isa($snak_obj)) {
39 1         8 err "Object isn't '$snak_obj'.";
40             }
41              
42 18 100       67 if (! exists $snaks_hr->{$key}->{$snak_o->property}) {
43 17         181 $snaks_hr->{$key}->{$snak_o->property} = [];
44             }
45 18 100 100     119 if (! @{$snaks_hr->{$key.'-order'}}
  18         104  
46 12     12   46 || none { $_ eq $snak_o->property } @{$snaks_hr->{$key.'-order'}}) {
  9         41  
47              
48 17         86 push @{$snaks_hr->{$key.'-order'}}, $snak_o->property;
  17         59  
49             }
50 18         132 push @{$snaks_hr->{$key}->{$snak_o->property}},
  18         48  
51             eval $struct_snak_obj.'::obj2struct($snak_o, $base_uri);';
52             }
53              
54 9         57 return $snaks_hr;
55             }
56              
57             sub struct2snaks_array_ref {
58 14     14 1 7115 my ($struct_hr, $key, $struct_snak_obj) = @_;
59              
60 14 100       50 if (! defined $struct_snak_obj) {
61 13         30 $struct_snak_obj = 'Wikibase::Datatype::Struct::Snak';
62             }
63 14         1031 eval "require $struct_snak_obj";
64 14 50       74 if ($EVAL_ERROR) {
65 0         0 err "Cannot load '$struct_snak_obj'";
66             }
67              
68 14         36 my $snaks_ar = [];
69 14         27 foreach my $property (@{$struct_hr->{$key.'-order'}}) {
  14         59  
70 20         37 push @{$snaks_ar}, map {
71 21         1195 eval $struct_snak_obj.'::struct2obj($_)';
72 20         35 } @{$struct_hr->{$key}->{$property}};
  20         53  
73 20 100       4815 if ($EVAL_ERROR) {
74 2         7 err $EVAL_ERROR;
75             }
76             }
77              
78 12         82 return $snaks_ar;
79             }
80              
81             1;
82              
83             __END__
84              
85             =pod
86              
87             =encoding utf8
88              
89             =head1 NAME
90              
91             Wikibase::Datatype::Struct::Utils - Wikibase structure serialization utilities.
92              
93             =head1 SYNOPSIS
94              
95             use Wikibase::Datatype::Struct::Utils qw(obj_array_ref2struct struct2snaks_array_ref);
96              
97             my $snaks_hr = obj_array_ref2struct($snaks_ar, $key, $base_uri, $snak_obj, $struct_snak_obj);
98             my $snaks_ar = struct2snaks_array_ref($struct_hr, $key, $struct_snak_obj);
99              
100             =head1 SUBROUTINES
101              
102             =head2 C<obj_array_ref2struct>
103              
104             my $snaks_hr = obj_array_ref2struct($snaks_ar, $key, $base_uri, $snak_obj);
105              
106             Helper subroutine for converting list of Snak objects to snaks structure.
107             This subroutine is used in Statement and Reference module.
108             C<$base_uri> is base URI of Wikibase system (e.g. http://test.wikidata.org/entity/).
109             C<$snak_obj> is object for snak (default value is 'Wikibase::Datatype::Snak').
110             C<$struct_snak_obj> is object for struct snak (default value is 'Wikibase::Datatype::Struct::Snak').
111              
112             Returns structure with multiple snaks.
113              
114             =head2 C<struct2snaks_array_ref>
115              
116             my $snaks_ar = struct2snaks_array_ref($struct_hr, $key, $struct_snak_obj);
117              
118             Helper subroutine for converting snaks structure to list of Snak objects.
119             This subroutine is used in Statement and Reference module.
120             C<$struct_snak_obj> is object for struct snak (default value is 'Wikibase::Datatype::Struct::Snak').
121              
122             Returns reference to array with snaks objects.
123              
124             =head1 ERRORS
125              
126             obj_array_ref2struct():
127             Base URI is required.
128             Object isn't 'Wikibase::Datatype::Snak'.
129              
130             struct2snaks_array_ref():
131             From Wikibase::Datatype::Snak::new():
132             From Wikibase::Datatype::Utils::check_required():
133             Parameter 'datatype' is required.
134             Parameter 'datavalue' is required.
135             Parameter 'property' is required.
136             From Wikibase::Datatype::Utils::check_isa():
137             Parameter 'datavalue' must be a 'Wikibase::Datatype::Value::%s' object.
138             Parameter 'datatype' = '%s' isn't supported.
139             Parameter 'property' must begin with 'P' and number after it.
140             Parameter 'snaktype' = '%s' isn't supported.
141             From Wikibase::Datatype::Struct::Snak::struct2obj():
142             From Wikibase::Datatype::Struct::Value::struct2obj():
143             Entity type '%s' is unsupported.
144             Type doesn't exist.
145             Type '%s' is unsupported.
146              
147             =head1 EXAMPLE1
148              
149             use strict;
150             use warnings;
151              
152             use Data::Printer;
153             use Wikibase::Datatype::Snak;
154             use Wikibase::Datatype::Struct::Utils qw(obj_array_ref2struct);
155             use Wikibase::Datatype::Value::Item;
156             use Wikibase::Datatype::Value::String;
157              
158             my $snak1 = Wikibase::Datatype::Snak->new(
159             'datatype' => 'wikibase-item',
160             'datavalue' => Wikibase::Datatype::Value::Item->new(
161             'value' => 'Q5',
162             ),
163             'property' => 'P31',
164             );
165             my $snak2 = Wikibase::Datatype::Snak->new(
166             'datatype' => 'math',
167             'datavalue' => Wikibase::Datatype::Value::String->new(
168             'value' => 'E = m c^2',
169             ),
170             'property' => 'P2534',
171             );
172              
173             # Convert list of snak objects to structure.
174             my $snaks_ar = obj_array_ref2struct([$snak1, $snak2], 'snaks',
175             'http://test.wikidata.org/entity/');
176              
177             # Dump to output.
178             p $snaks_ar;
179              
180             # Output:
181             # \ {
182             # snaks {
183             # P31 [
184             # [0] {
185             # datatype "wikibase-item",
186             # datavalue {
187             # type "wikibase-entityid",
188             # value {
189             # entity-type "item",
190             # id "Q5",
191             # numeric-id 5
192             # }
193             # },
194             # property "P31",
195             # snaktype "value"
196             # }
197             # ],
198             # P2534 [
199             # [0] {
200             # datatype "math",
201             # datavalue {
202             # type "string",
203             # value "E = m c^2"
204             # },
205             # property "P2534",
206             # snaktype "value"
207             # }
208             # ]
209             # },
210             # snaks-order [
211             # [0] "P31",
212             # [1] "P2534"
213             # ]
214             # }
215              
216             =head1 EXAMPLE2
217              
218             use strict;
219             use warnings;
220              
221             use Wikibase::Datatype::Struct::Utils qw(struct2snaks_array_ref);
222              
223             my $struct_hr = {
224             'snaks' => {
225             'P31' => [{
226             'datatype' => 'wikibase-item',
227             'datavalue' => {
228             'type' => 'wikibase-entityid',
229             'value' => {
230             'entity-type' => 'item',
231             'id' => 'Q5',
232             'numeric-id' => 5,
233             },
234             },
235             'property' => 'P31',
236             'snaktype' => 'value',
237              
238             }],
239             'P2534' => [{
240             'datatype' => 'math',
241             'datavalue' => {
242             'type' => 'string',
243             'value' => 'E = m c^2',
244             },
245             'property' => 'P2534',
246             'snaktype' => 'value',
247             }],
248             },
249             'snaks-order' => [
250             'P31',
251             'P2534',
252             ],
253             };
254              
255             # Convert snaks structure to list of Snak objects.
256             my $snaks_ar = struct2snaks_array_ref($struct_hr, 'snaks');
257              
258             # Print out.
259             foreach my $snak (@{$snaks_ar}) {
260             print 'Property: '.$snak->property."\n";
261             print 'Type: '.$snak->datatype."\n";
262             print 'Value: '.$snak->datavalue->value."\n";
263             print "\n";
264             }
265              
266             # Output:
267             # Property: P31
268             # Type: wikibase-item
269             # Value: Q5
270             #
271             # Property: P2534
272             # Type: math
273             # Value: E = m c^2
274             #
275              
276             =head1 DEPENDENCIES
277              
278             L<Error::Pure>,
279             L<Exporter>,
280             L<List::MoreUtils>.
281              
282             =head1 SEE ALSO
283              
284             =over
285              
286             =item L<Wikibase::Datatype::Struct>
287              
288             Wikibase structure serialization.
289              
290             =back
291              
292             =head1 REPOSITORY
293              
294             L<https://github.com/michal-josef-spacek/Wikibase-Datatype-Struct>
295              
296             =head1 AUTHOR
297              
298             Michal Josef Špaček L<mailto:skim@cpan.org>
299              
300             L<http://skim.cz>
301              
302             =head1 LICENSE AND COPYRIGHT
303              
304             © Michal Josef Špaček 2020-2021
305              
306             BSD 2-Clause License
307              
308             =head1 VERSION
309              
310             0.08
311              
312             =cut