File Coverage

lib/Data/Identifier/Cloudlet.pm
Criterion Covered Total %
statement 55 109 50.4
branch 10 56 17.8
condition 5 45 11.1
subroutine 11 16 68.7
pod 10 10 100.0
total 91 236 38.5


line stmt bran cond sub pod time code
1             # Copyright (c) 2023-2025 Philipp Schafft
2              
3             # licensed under Artistic License 2.0 (see LICENSE file)
4              
5             # ABSTRACT: format independent identifier object
6              
7              
8             package Data::Identifier::Cloudlet;
9              
10 2     2   5233 use v5.14;
  2         7  
11 2     2   10 use strict;
  2         4  
  2         45  
12 2     2   6 use warnings;
  2         3  
  2         360  
13              
14 2     2   12 use parent qw(Data::Identifier::Interface::Userdata);
  2         4  
  2         19  
15              
16 2     2   134 use Carp;
  2         4  
  2         223  
17              
18 2     2   15 use Data::Identifier;
  2         2  
  2         16  
19              
20             our $VERSION = v0.28;
21              
22             my %_valid_new_opts = (
23             db => 'Data::TagDB',
24             extractor => 'Data::URIID',
25             fii => 'File::Information',
26             store => 'File::FStore',
27             );
28              
29              
30             sub new {
31 5     5 1 16 my ($pkg, %opts) = @_;
32 5         10 my $self = bless {}, $pkg;
33              
34 5 50       14 if (defined(my $from = delete($opts{from}))) {
35 0 0 0     0 if (defined(delete($opts{root})) || defined(delete($opts{entry}))) {
36 0         0 croak 'root and entry given with from';
37             }
38              
39 0 0       0 if (eval {$from->isa(__PACKAGE__)}) {
  0         0  
40 0   0     0 $opts{$_} //= $from->{$_} foreach keys %_valid_new_opts;
41              
42 0         0 $opts{root} = [$from->roots];
43 0         0 $opts{entry} = [$from->entries];
44             }
45              
46 0 0 0     0 if (!ref($from) || ref($from) eq 'ARRAY' || eval {$from->can('ise')}) {
  0   0     0  
47 0         0 $opts{root} = $from;
48             }
49              
50 0 0       0 croak 'Unknown/Unsupported from' unless defined $opts{root};
51             }
52              
53 5         18 foreach my $key (keys %_valid_new_opts) {
54 20   50     37 my $v = delete($opts{$key}) // next;
55              
56 0 0       0 croak 'Bad type for key '.$key unless $v->isa($_valid_new_opts{$key});
57              
58 0         0 $self->{$key} = $v;
59             }
60              
61 5         9 foreach my $key (qw(root entry)) {
62 10   100     20 my $v = delete($opts{$key}) // next;
63              
64 8 100       20 $v = [$v] unless ref($v) eq 'ARRAY';
65              
66 8         10 foreach my $s (@{$v}) {
  8         14  
67 9 50       12 unless (eval {$s->can('ise')}) {
  9         30  
68 0         0 $s = Data::Identifier->new(from => $s);
69             }
70             }
71              
72 8         9 $v = {map {$_->ise => $_} @{$v}};
  9         20  
  8         15  
73              
74 8         24 $self->{$key} = $v;
75             }
76              
77 5 50       9 croak 'Stray options passed' if scalar keys %opts;
78              
79 5 50       11 croak 'No root given' unless defined $self->{root};
80              
81 5   100     5 $self->{entry} = {%{$self->{entry}//{}}, %{$self->{root}}};
  5         33  
  5         15  
82              
83 5         27 return $self;
84             }
85              
86              
87             sub as {
88 0     0 1 0 my ($self, $as, %opts) = @_;
89 0         0 my %extra = %opts{qw(db extractor fii store)};
90              
91 0 0 0     0 $as = $opts{rawtype} if $as eq 'raw' && defined($opts{rawtype});
92              
93 0 0 0     0 return $self if ($as =~ /^[A-Z]/ || $as =~ /::/) && eval {$self->isa($as)};
  0   0     0  
94              
95 0 0       0 if (eval {$self->isa(__PACKAGE__)}) {
  0         0  
96 0   0     0 $extra{$_} //= $self->{$_} foreach qw(db extractor fii store);
97             }
98              
99 0 0 0     0 if (!ref($self) || ref($self) eq 'ARRAY') {
100 0         0 $self = __PACKAGE__->new(root => $self, %extra);
101 0 0 0     0 return $self if ($as =~ /^[A-Z]/ || $as =~ /::/) && eval {$self->isa($as)};
  0   0     0  
102             }
103              
104 0 0       0 return $opts{default} if exists $opts{default};
105 0         0 croak 'Unknown/Unsupported as: '.$as;
106             }
107              
108              
109             sub roots {
110 4     4 1 1854 my ($self, %opts) = @_;
111              
112 4 50       13 if (defined $opts{as}) {
113 0   0     0 my %extra = map {$_ => ($opts{$_} // $self->{$_})} qw(db extractor fii store);
  0         0  
114             return map {$_->Data::Identifier::as(
115             $opts{as},
116 0         0 %extra,
117 0         0 )} values %{$self->{root}};
  0         0  
118             }
119              
120 4         4 return values %{$self->{root}};
  4         23  
121             }
122              
123              
124             sub entries {
125 4     4 1 12 my ($self, %opts) = @_;
126              
127 4 50       10 if (defined $opts{as}) {
128 0   0     0 my %extra = map {$_ => ($opts{$_} // $self->{$_})} qw(db extractor fii store);
  0         0  
129             return map {$_->Data::Identifier::as(
130             $opts{as},
131 0         0 %extra,
132 0         0 )} values %{$self->{root}};
  0         0  
133             }
134              
135 4         6 return values %{$self->{entry}};
  4         18  
136             }
137              
138              
139             sub is_root {
140 3     3 1 7 my ($self, $tag) = @_;
141 3 50       5 $tag = Data::Identifier->new(from => $tag) unless eval {$tag->can('ise')};
  3         11  
142 3         8 return exists $self->{root}{$tag->ise};
143             }
144              
145              
146             sub is_entry {
147 3     3 1 7 my ($self, $tag) = @_;
148 3 50       4 $tag = Data::Identifier->new(from => $tag) unless eval {$tag->can('ise')};
  3         13  
149 3         8 return exists $self->{entry}{$tag->ise};
150             }
151              
152              
153             #@returns Data::TagDB
154             sub db {
155 0     0 1   my ($self, %opts) = @_;
156 0 0         return $self->{db} if defined $self->{db};
157 0 0         return $opts{default} if exists $opts{default};
158 0           croak 'No database known';
159             }
160              
161             #@returns Data::URIID
162             sub extractor {
163 0     0 1   my ($self, %opts) = @_;
164 0 0         return $self->{extractor} if defined $self->{extractor};
165 0 0         return $opts{default} if exists $opts{default};
166 0           croak 'No extractor known';
167             }
168              
169             #@returns File::Information
170             sub fii {
171 0     0 1   my ($self, %opts) = @_;
172 0 0         return $self->{fii} if defined $self->{fii};
173 0 0         return $opts{default} if exists $opts{default};
174 0           croak 'No fii known';
175             }
176              
177             #@returns File::FStore
178             sub store {
179 0     0 1   my ($self, %opts) = @_;
180 0 0         return $self->{store} if defined $self->{store};
181 0 0         return $opts{default} if exists $opts{default};
182 0           croak 'No store known';
183             }
184              
185             1;
186              
187             __END__