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 38     38   1042041 use base qw(Exporter);
  38         128  
  38         3585  
4 38     38   296 use strict;
  38         96  
  38         845  
5 38     38   199 use warnings;
  38         102  
  38         1092  
6              
7 38     38   1231 use English;
  38         7949  
  38         385  
8 38     38   20685 use Error::Pure qw(err);
  38         15584  
  38         1480  
9 38     38   4078 use List::MoreUtils qw(none);
  38         84491  
  38         325  
10              
11             Readonly::Array our @EXPORT_OK => qw(obj_array_ref2struct struct2snaks_array_ref);
12              
13             our $VERSION = 0.11;
14              
15             sub obj_array_ref2struct {
16 12     12 1 6739 my ($snaks_ar, $key, $base_uri, $snak_obj, $struct_snak_obj) = @_;
17              
18 12 100       76 if (! defined $snak_obj) {
19 11         24 $snak_obj = 'Wikibase::Datatype::Snak';
20             }
21 12 100       39 if (! defined $struct_snak_obj) {
22 11         21 $struct_snak_obj = 'Wikibase::Datatype::Struct::Snak';
23             }
24 12         965 eval "require $struct_snak_obj";
25 12 50       74 if ($EVAL_ERROR) {
26 0         0 err "Cannot load '$struct_snak_obj'";
27             }
28              
29 12 100       47 if (! defined $base_uri) {
30 1         9 err 'Base URI is required.';
31             }
32              
33 11         56 my $snaks_hr = {
34             $key.'-order' => [],
35             $key => {},
36             };
37 11         24 foreach my $snak_o (@{$snaks_ar}) {
  11         35  
38 22 100       104 if (! $snak_o->isa($snak_obj)) {
39 1         12 err "Object isn't '$snak_obj'.";
40             }
41              
42 21 100       84 if (! exists $snaks_hr->{$key}->{$snak_o->property}) {
43 20         192 $snaks_hr->{$key}->{$snak_o->property} = [];
44             }
45 21 100 100     132 if (! @{$snaks_hr->{$key.'-order'}}
  21         131  
46 15     15   60 || none { $_ eq $snak_o->property } @{$snaks_hr->{$key.'-order'}}) {
  11         49  
47              
48 20         96 push @{$snaks_hr->{$key.'-order'}}, $snak_o->property;
  20         60  
49             }
50 21         145 push @{$snaks_hr->{$key}->{$snak_o->property}},
  21         69  
51             eval $struct_snak_obj.'::obj2struct($snak_o, $base_uri);';
52             }
53              
54 10         72 return $snaks_hr;
55             }
56              
57             sub struct2snaks_array_ref {
58 20     20 1 11619 my ($struct_hr, $key, $struct_snak_obj) = @_;
59              
60 20 100       72 if (! defined $struct_snak_obj) {
61 19         55 $struct_snak_obj = 'Wikibase::Datatype::Struct::Snak';
62             }
63 20         1391 eval "require $struct_snak_obj";
64 20 50       110 if ($EVAL_ERROR) {
65 0         0 err "Cannot load '$struct_snak_obj'";
66             }
67              
68 20         54 my $snaks_ar = [];
69 20         42 foreach my $property (@{$struct_hr->{$key.'-order'}}) {
  20         99  
70 23         49 push @{$snaks_ar}, map {
71 24         1464 eval $struct_snak_obj.'::struct2obj($_)';
72 23         42 } @{$struct_hr->{$key}->{$property}};
  23         72  
73 23 100       3874 if ($EVAL_ERROR) {
74 2         7 err $EVAL_ERROR;
75             }
76             }
77              
78 18         158 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             =for comment filename=utils_obj_array_ref2struct.pl
150              
151             use strict;
152             use warnings;
153              
154             use Data::Printer;
155             use Wikibase::Datatype::Snak;
156             use Wikibase::Datatype::Struct::Utils qw(obj_array_ref2struct);
157             use Wikibase::Datatype::Value::Item;
158             use Wikibase::Datatype::Value::String;
159              
160             my $snak1 = Wikibase::Datatype::Snak->new(
161             'datatype' => 'wikibase-item',
162             'datavalue' => Wikibase::Datatype::Value::Item->new(
163             'value' => 'Q5',
164             ),
165             'property' => 'P31',
166             );
167             my $snak2 = Wikibase::Datatype::Snak->new(
168             'datatype' => 'math',
169             'datavalue' => Wikibase::Datatype::Value::String->new(
170             'value' => 'E = m c^2',
171             ),
172             'property' => 'P2534',
173             );
174              
175             # Convert list of snak objects to structure.
176             my $snaks_ar = obj_array_ref2struct([$snak1, $snak2], 'snaks',
177             'http://test.wikidata.org/entity/');
178              
179             # Dump to output.
180             p $snaks_ar;
181              
182             # Output:
183             # \ {
184             # snaks {
185             # P31 [
186             # [0] {
187             # datatype "wikibase-item",
188             # datavalue {
189             # type "wikibase-entityid",
190             # value {
191             # entity-type "item",
192             # id "Q5",
193             # numeric-id 5
194             # }
195             # },
196             # property "P31",
197             # snaktype "value"
198             # }
199             # ],
200             # P2534 [
201             # [0] {
202             # datatype "math",
203             # datavalue {
204             # type "string",
205             # value "E = m c^2"
206             # },
207             # property "P2534",
208             # snaktype "value"
209             # }
210             # ]
211             # },
212             # snaks-order [
213             # [0] "P31",
214             # [1] "P2534"
215             # ]
216             # }
217              
218             =head1 EXAMPLE2
219              
220             =for comment filename=utils_struct2snaks_array_ref.pl
221              
222             use strict;
223             use warnings;
224              
225             use Wikibase::Datatype::Struct::Utils qw(struct2snaks_array_ref);
226              
227             my $struct_hr = {
228             'snaks' => {
229             'P31' => [{
230             'datatype' => 'wikibase-item',
231             'datavalue' => {
232             'type' => 'wikibase-entityid',
233             'value' => {
234             'entity-type' => 'item',
235             'id' => 'Q5',
236             'numeric-id' => 5,
237             },
238             },
239             'property' => 'P31',
240             'snaktype' => 'value',
241              
242             }],
243             'P2534' => [{
244             'datatype' => 'math',
245             'datavalue' => {
246             'type' => 'string',
247             'value' => 'E = m c^2',
248             },
249             'property' => 'P2534',
250             'snaktype' => 'value',
251             }],
252             },
253             'snaks-order' => [
254             'P31',
255             'P2534',
256             ],
257             };
258              
259             # Convert snaks structure to list of Snak objects.
260             my $snaks_ar = struct2snaks_array_ref($struct_hr, 'snaks');
261              
262             # Print out.
263             foreach my $snak (@{$snaks_ar}) {
264             print 'Property: '.$snak->property."\n";
265             print 'Type: '.$snak->datatype."\n";
266             print 'Value: '.$snak->datavalue->value."\n";
267             print "\n";
268             }
269              
270             # Output:
271             # Property: P31
272             # Type: wikibase-item
273             # Value: Q5
274             #
275             # Property: P2534
276             # Type: math
277             # Value: E = m c^2
278             #
279              
280             =head1 DEPENDENCIES
281              
282             L<Error::Pure>,
283             L<Exporter>,
284             L<List::MoreUtils>.
285              
286             =head1 SEE ALSO
287              
288             =over
289              
290             =item L<Wikibase::Datatype::Struct>
291              
292             Wikibase structure serialization.
293              
294             =back
295              
296             =head1 REPOSITORY
297              
298             L<https://github.com/michal-josef-spacek/Wikibase-Datatype-Struct>
299              
300             =head1 AUTHOR
301              
302             Michal Josef Špaček L<mailto:skim@cpan.org>
303              
304             L<http://skim.cz>
305              
306             =head1 LICENSE AND COPYRIGHT
307              
308             © 2020-2023 Michal Josef Špaček
309              
310             BSD 2-Clause License
311              
312             =head1 VERSION
313              
314             0.11
315              
316             =cut