File Coverage

blib/lib/Data/GUID/Any.pm
Criterion Covered Total %
statement 142 143 99.3
branch 9 12 75.0
condition 1 3 33.3
subroutine 49 49 100.0
pod n/a
total 201 207 97.1


line stmt bran cond sub pod time code
1 1     1   994 use 5.006;
  1     1   3  
  1     1   38  
  1     1   769  
  1     1   8  
  1     1   60  
  1     1   24091  
  1         5  
  1         34  
  1         746  
  1         4  
  1         43  
  1         14018  
  1         7  
  1         39  
  1         701  
  1         4  
  1         45  
  1         10092  
  1         8  
  1         34  
2 1     1   6 use strict;
  1     1   2  
  1     1   32  
  1     1   8  
  1     1   5  
  1     1   133  
  1     1   5  
  1         2  
  1         423  
  1         6  
  1         2  
  1         38  
  1         10  
  1         3  
  1         38  
  1         6  
  1         3  
  1         40  
  1         11  
  1         3  
  1         40  
3 1     1   5 use warnings;
  1     1   1  
  1     1   52  
  1     1   10  
  1     1   5  
  1     1   115  
  1     1   11  
  1         8  
  1         85  
  1         7  
  1         3  
  1         73  
  1         8  
  1         6  
  1         72  
  1         6  
  1         3  
  1         51  
  1         8  
  1         4  
  1         78  
4             package Data::GUID::Any;
5             # ABSTRACT: Generic interface for GUID/UUID creation
6             our $VERSION = '0.004'; # VERSION
7              
8 1     1   7 use IPC::Cmd;
  1     1   472903  
  1     1   61  
  1     1   5  
  1     1   2  
  1     1   167  
  1     1   4  
  1         3  
  1         151  
  1         6  
  1         2  
  1         52  
  1         8  
  1         6  
  1         44  
  1         10  
  1         3  
  1         56  
  1         8  
  1         2  
  1         45  
9 1     1   13 use Exporter;
  1     1   2  
  1     1   1294  
  1     1   9  
  1     1   1  
  1     1   165  
  1     1   5  
  1         6  
  1         442  
  1         5  
  1         2  
  1         171  
  1         5  
  1         2  
  1         132  
  1         7  
  1         1  
  1         162  
  1         6  
  1         2  
  1         140  
10             our @ISA = qw/Exporter/;
11             our @EXPORT_OK = qw/ guid_as_string v1_guid_as_string v4_guid_as_string/;
12              
13             our ($Using_vX, $Using_v1, $Using_v4) = ("") x 3;
14             our $UC = 1;
15              
16             #--------------------------------------------------------------------------#
17              
18             my $hex = "a-z0-9";
19              
20             # case insensitive, since used to check if generators are functioning
21             sub _looks_like_guid {
22 3     3   5 my $guid = shift;
23 3         153 return $guid =~ /[$hex]{8}-[$hex]{4}-[$hex]{4}-[$hex]{4}-[$hex]{12}/i;
24             }
25              
26             #--------------------------------------------------------------------------#
27              
28             sub _xc {
29 5 100   5   781 return $UC ? uc($_[0]) : lc($_[0]);
30             }
31              
32             #--------------------------------------------------------------------------#
33              
34             # state variables for generator closures
35             my ($dumt_v1, $dumt_v4, $uuid_v1, $uuid_v4) = (undef) x 4; # reset if reloaded
36              
37             my %generators = (
38             # v1 or v4
39             'Data::UUID::MT' => {
40             type => 'module',
41             v1 => sub {
42             $dumt_v1 ||= Data::UUID::MT->new(version => 1);
43             return _xc( $dumt_v1->create_string );
44             },
45             v4 => sub {
46             $dumt_v4 ||= Data::UUID::MT->new(version => 4);
47             return _xc( $dumt_v4->create_string );
48             },
49             },
50             'Data::UUID::LibUUID' => {
51             type => 'module',
52             v1 => sub { return _xc( Data::UUID::LibUUID::new_uuid_string(2) ) },
53             v4 => sub { return _xc( Data::UUID::LibUUID::new_uuid_string(4) ) },
54             vX => sub { return _xc( Data::UUID::LibUUID::new_uuid_string() ) },
55             },
56             'UUID::Tiny' => {
57             type => 'module',
58 2     2   9 v1 => sub { return _xc( UUID::Tiny::create_UUID_as_string(UUID::Tiny::UUID_V1()) ) },
59 3     3   8573 v4 => sub { return _xc( UUID::Tiny::create_UUID_as_string(UUID::Tiny::UUID_V4()) ) },
60             },
61             'uuid' => {
62             type => 'binary',
63             v1 => sub {
64             $uuid_v1 ||= IPC::Cmd::can_run('uuid');
65             chomp( my $guid = qx/$uuid_v1 -v1/ ); return _xc( $guid );
66             },
67             v4 => sub {
68             $uuid_v4 ||= IPC::Cmd::can_run('uuid');
69             chomp( my $guid = qx/$uuid_v4 -v4/ ); return _xc( $guid );
70             },
71             },
72             # v1 only
73             'Data::GUID' => {
74             type => 'module',
75             v1 => sub { return _xc( Data::GUID->new->as_string ) },
76             },
77             'Data::UUID' => {
78             type => 'module',
79             v1 => sub { return _xc( Data::UUID->new->create_str ) },
80             },
81             # system dependent or custom
82             'UUID' => {
83             type => 'module',
84             vX => sub { my ($u,$s); UUID::generate($u); UUID::unparse($u, $s); return _xc( $s ) },
85             },
86             'Win32' => {
87             type => 'module',
88             vX => sub { my $guid = Win32::GuidGen(); return _xc( substr($guid,1,-1) ) },
89             },
90             'APR::UUID' => {
91             type => 'module',
92             vX => sub { return _xc( APR::UUID->new->format ) },
93             },
94             );
95              
96             our $NO_BINARY; # for testing
97             sub _is_available {
98 19     19   25 my ($name) = @_;
99 19 100       52 if ( $generators{$name}{type} eq 'binary' ) {
100 3 50       14 return $NO_BINARY ? undef : IPC::Cmd::can_run($name);
101             }
102             else {
103 16         1021 return eval "require $name";
104             }
105             }
106              
107             sub _best_generator {
108 3     3   5 my ($list) = @_;
109 3         6 for my $option ( @$list ) {
110 19         11634 my ($name, $version) = @$option;
111 19 50       55 next unless my $g = $generators{$name};
112 19 100       33 next unless _is_available($name);
113 3 50 33     20 return ($name, $g->{$version})
114             if $g->{$version} && _looks_like_guid( $g->{$version}->() );
115             }
116 0         0 return;
117             }
118              
119             #--------------------------------------------------------------------------#
120              
121             my %sets = (
122             any => [
123             ['Data::UUID::MT' => 'v4'],
124             ['Data::GUID' => 'v1'],
125             ['Data::UUID' => 'v1'],
126             ['Data::UUID::LibUUID' => 'vX'],
127             ['UUID' => 'vX'],
128             ['Win32' => 'vX'],
129             ['uuid' => 'v1'],
130             ['APR::UUID' => 'vX'],
131             ['UUID::Tiny' => 'v1'],
132             ],
133             v1 => [
134             ['Data::UUID::MT' => 'v1'],
135             ['Data::GUID' => 'v1'],
136             ['Data::UUID' => 'v1'],
137             ['Data::UUID::LibUUID' => 'v1'],
138             ['uuid' => 'v1'],
139             ['UUID::Tiny' => 'v1'],
140             ],
141             v4 => [
142             ['Data::UUID::MT' => 'v4'],
143             ['Data::UUID::LibUUID' => 'v4'],
144             ['uuid' => 'v4'],
145             ['UUID::Tiny' => 'v4'],
146             ],
147             );
148              
149 3     3   10 sub _generator_set { return $sets{$_[0]} }
150              
151             {
152 1     1   8 no warnings qw/once redefine/;
  1     1   3  
  1     1   281  
  1     1   1291  
  1     1   3  
  1     1   330  
  1     1   2157  
  1         3  
  1         364  
  1         1258  
  1         2  
  1         334  
  1         1427  
  1         3  
  1         262  
  1         1129  
  1         2  
  1         3142  
  1         1235  
  1         3  
  1         447  
153             {
154             my ($n, $s) = _best_generator(_generator_set("any"));
155             die "Couldn't find a GUID provider" unless $n;
156             *guid_as_string = $s;
157             $Using_vX = $n;
158             }
159             {
160             my ($n, $s) = _best_generator(_generator_set("v1"));
161             *v1_guid_as_string = $s || sub { die "No v1 GUID provider found\n" };
162             $Using_v1 = $n || '';
163             }
164             {
165             my ($n, $s) = _best_generator(_generator_set("v4"));
166             *v4_guid_as_string = $s || sub { die "No v4 GUID provider found\n" };
167             $Using_v4 = $n || '';
168             }
169             }
170              
171             1;
172              
173             __END__