File Coverage

blib/lib/Text/KDL/XS/Value.pm
Criterion Covered Total %
statement 23 34 67.6
branch 8 26 30.7
condition 0 3 0.0
subroutine 10 15 66.6
pod 11 12 91.6
total 52 90 57.7


line stmt bran cond sub pod time code
1             package Text::KDL::XS::Value;
2              
3 7     7   62 use strict;
  7         14  
  7         261  
4 7     7   33 use warnings;
  7         15  
  7         382  
5              
6 7     7   38 use Carp ();
  7         12  
  7         3958  
7              
8             # A Value is a blessed hashref with these slots:
9             # type : 'null' | 'bool' | 'number' | 'string'
10             # kind : 'integer' | 'float' | 'string' (only when type=number)
11             # value : underlying scalar (IV/NV/PV) or undef
12             # type_annotation : string, optional KDL type tag like "u32"
13              
14             sub new {
15 0     0 0 0 my ($class, %args) = @_;
16             Carp::croak("Text::KDL::XS::Value->new: 'type' is required")
17 0 0       0 unless defined $args{type};
18              
19             return bless {
20             type => $args{type},
21             kind => $args{kind},
22             value => $args{value},
23             type_annotation => $args{type_annotation},
24 0         0 }, $class;
25             }
26              
27 0     0 1 0 sub type { $_[0]->{type} }
28 3     3 1 24 sub kind { $_[0]->{kind} }
29 1     1 1 7 sub type_annotation { $_[0]->{type_annotation} }
30              
31 2     2 1 13 sub is_null { $_[0]->{type} eq 'null' }
32 4     4 1 19 sub is_bool { $_[0]->{type} eq 'bool' }
33 4     4 1 47 sub is_number { $_[0]->{type} eq 'number' }
34 0     0 1 0 sub is_string { $_[0]->{type} eq 'string' }
35              
36             # Raw underlying scalar (already typed in XS).
37 0     0 1 0 sub value { $_[0]->{value} }
38              
39             # Returns a Perl number suitable for arithmetic when possible.
40             # Arbitrary-precision integers are still returned as strings; callers
41             # who need bigint semantics should pass C to Math::BigInt.
42             sub as_number {
43 0     0 1 0 my ($self) = @_;
44 0 0       0 return undef if $self->{type} eq 'null';
45             return $self->{type} eq 'bool' ? ($self->{value} ? 1 : 0) : $self->{value} + 0
46 0 0       0 if $self->{type} ne 'number';
    0          
    0          
47 0 0 0     0 return $self->{value} if defined $self->{kind} && $self->{kind} ne 'string';
48             # string-encoded number - preserve as string-on-the-wire but coerce at use
49 0         0 return $self->{value};
50             }
51              
52             sub as_string {
53 15     15 1 33 my ($self) = @_;
54 15 50       55 return undef if $self->{type} eq 'null';
55 15 0       38 return $self->{value} ? 'true' : 'false' if $self->{type} eq 'bool';
    50          
56 15 50       88 return defined $self->{value} ? "$self->{value}" : undef;
57             }
58              
59             # Best-effort native Perl scalar:
60             # null -> undef
61             # bool -> 1/0
62             # number -> IV / NV / string (for arbitrary-precision)
63             # string -> PV
64             sub as_perl {
65 28     28 1 67 my ($self) = @_;
66 28         46 my $t = $self->{type};
67 28 50       62 return undef if $t eq 'null';
68 28 100       70 return $self->{value} ? 1 : 0 if $t eq 'bool';
    100          
69 24         104 return $self->{value};
70             }
71              
72             1;
73              
74             __END__