File Coverage

blib/lib/Lib/Pepper/OptionList.pm
Criterion Covered Total %
statement 41 177 23.1
branch 0 38 0.0
condition 0 12 0.0
subroutine 14 26 53.8
pod 11 11 100.0
total 66 264 25.0


line stmt bran cond sub pod time code
1             package Lib::Pepper::OptionList;
2             #---AUTOPRAGMASTART---
3 5     5   81 use v5.42;
  5         21  
4 5     5   36 use strict;
  5         12  
  5         156  
5 5     5   27 use diagnostics;
  5         12  
  5         37  
6 5     5   226 use mro 'c3';
  5         10  
  5         37  
7 5     5   186 use English;
  5         9  
  5         41  
8 5     5   2472 use Carp qw[carp croak confess cluck longmess shortmess];
  5         10  
  5         698  
9             our $VERSION = 0.5;
10 5     5   40 use autodie qw( close );
  5         12  
  5         42  
11 5     5   1940 use Array::Contains;
  5         44  
  5         360  
12 5     5   36 use utf8;
  5         9  
  5         41  
13 5     5   239 use Data::Dumper;
  5         11  
  5         283  
14 5     5   30 use Data::Printer;
  5         11  
  5         42  
15             #---AUTOPRAGMAEND---
16              
17              
18 5     5   534 use Lib::Pepper;
  5         10  
  5         232  
19 5     5   28 use Lib::Pepper::Exception;
  5         10  
  5         286  
20 5     5   37 use Lib::Pepper::Constants qw(:special);
  5         60  
  5         11915  
21              
22 0     0 1   sub new($class, $handle = undef) {
  0            
  0            
  0            
23 0           my $self = {
24             handle => undef,
25             owned => 0,
26             };
27              
28 0           bless $self, $class;
29              
30 0 0         if(defined $handle) {
31             # Wrap an existing handle
32 0           $self->{handle} = $handle;
33 0           $self->{owned} = 0;
34             } else {
35             # Create a new option list
36 0           my ($result, $newHandle) = Lib::Pepper::pepOptionListCreate();
37 0           Lib::Pepper::Exception->checkResult($result, 'pepOptionListCreate');
38 0           $self->{handle} = $newHandle;
39 0           $self->{owned} = 1;
40             }
41              
42 0           return $self;
43             }
44              
45 0     0 1   sub getHandle($self) {
  0            
  0            
46 0           return $self->{handle};
47             }
48              
49 0     0 1   sub getString($self, $key) {
  0            
  0            
  0            
50 0 0         if(!defined $key) {
51 0           croak('getString: key parameter is required');
52             }
53              
54 0           my ($result, $value) = Lib::Pepper::pepOptionListGetStringElement($self->{handle}, $key);
55 0           Lib::Pepper::Exception->checkResult($result, "getString('$key')");
56              
57 0           return $value;
58             }
59              
60 0     0 1   sub getInt($self, $key) {
  0            
  0            
  0            
61 0 0         if(!defined $key) {
62 0           croak('getInt: key parameter is required');
63             }
64              
65 0           my ($result, $value) = Lib::Pepper::pepOptionListGetIntElement($self->{handle}, $key);
66 0           Lib::Pepper::Exception->checkResult($result, "getInt('$key')");
67              
68 0           return $value;
69             }
70              
71 0     0 1   sub getChild($self, $key) {
  0            
  0            
  0            
72 0 0         if(!defined $key) {
73 0           croak('getChild: key parameter is required');
74             }
75              
76 0           my ($result, $childHandle) = Lib::Pepper::pepOptionListGetChildOptionListElement($self->{handle}, $key);
77 0           Lib::Pepper::Exception->checkResult($result, "getChild('$key')");
78              
79             # Wrap the child handle in a new OptionList object (non-owned)
80 0           return Lib::Pepper::OptionList->new($childHandle);
81             }
82              
83 0     0 1   sub addString($self, $key, $value) {
  0            
  0            
  0            
  0            
84 0 0         if(!defined $key) {
85 0           croak('addString: key parameter is required');
86             }
87 0 0         if(!defined $value) {
88 0           croak('addString: value parameter is required');
89             }
90              
91 0           my $result = Lib::Pepper::pepOptionListAddStringElement($self->{handle}, $key, $value);
92 0           Lib::Pepper::Exception->checkResult($result, "addString('$key')");
93              
94 0           return $self;
95             }
96              
97 0     0 1   sub addInt($self, $key, $value) {
  0            
  0            
  0            
  0            
98 0 0         if(!defined $key) {
99 0           croak('addInt: key parameter is required');
100             }
101 0 0         if(!defined $value) {
102 0           croak('addInt: value parameter is required');
103             }
104              
105 0           my $result = Lib::Pepper::pepOptionListAddIntElement($self->{handle}, $key, $value);
106 0           Lib::Pepper::Exception->checkResult($result, "addInt('$key')");
107              
108 0           return $self;
109             }
110              
111 0     0 1   sub addChild($self, $key, $childOptionList) {
  0            
  0            
  0            
  0            
112 0 0         if(!defined $key) {
113 0           croak('addChild: key parameter is required');
114             }
115 0 0 0       if(!defined $childOptionList || !ref($childOptionList) || !$childOptionList->isa('Lib::Pepper::OptionList')) {
      0        
116 0           croak('addChild: childOptionList must be a Lib::Pepper::OptionList object');
117             }
118              
119 0           my $childHandle = $childOptionList->getHandle();
120 0           my $result = Lib::Pepper::pepOptionListAddChildOptionListElement($self->{handle}, $key, $childHandle);
121 0           Lib::Pepper::Exception->checkResult($result, "addChild('$key')");
122              
123 0           return $self;
124             }
125              
126 0     0 1   sub getElementList($self) {
  0            
  0            
127 0           my ($result, $elementList) = Lib::Pepper::pepOptionListGetElementList($self->{handle});
128 0           Lib::Pepper::Exception->checkResult($result, 'getElementList');
129              
130             # Parse comma-separated list
131 0 0 0       if(!defined $elementList || $elementList eq '') {
132 0           return [];
133             }
134              
135 0           my @elements = split(/,/, $elementList);
136 0           return \@elements;
137             }
138              
139 0     0 1   sub toHashref($self) {
  0            
  0            
140 0           my $elements = $self->getElementList();
141 0           my $hashref = {};
142              
143 0           for my $key (@{$elements}) {
  0            
144             # Try to get as int first
145 0           my ($result, $value) = Lib::Pepper::pepOptionListGetIntElement($self->{handle}, $key);
146              
147 0 0         if(Lib::Pepper::Exception->isSuccess($result)) {
148 0           $hashref->{$key} = $value;
149 0           next;
150             }
151              
152             # Try as string
153 0           ($result, $value) = Lib::Pepper::pepOptionListGetStringElement($self->{handle}, $key);
154              
155 0 0         if(Lib::Pepper::Exception->isSuccess($result)) {
156 0           $hashref->{$key} = $value;
157 0           next;
158             }
159              
160             # Try as child option list
161 0           ($result, my $childHandle) = Lib::Pepper::pepOptionListGetChildOptionListElement($self->{handle}, $key);
162              
163 0 0         if(Lib::Pepper::Exception->isSuccess($result)) {
164 0           my $childList = Lib::Pepper::OptionList->new($childHandle);
165 0           $hashref->{$key} = $childList->toHashref();
166 0           next;
167             }
168              
169             # If we get here, we couldn't get the value
170 0           carp("Warning: Could not retrieve value for key '$key'");
171             }
172              
173 0           return $hashref;
174             }
175              
176 0     0 1   sub fromHashref($class, $hashref) {
  0            
  0            
  0            
177 0 0 0       if(!defined $hashref || ref($hashref) ne 'HASH') {
178 0           croak('fromHashref: hashref parameter must be a hash reference');
179             }
180              
181 0           my $optionList = $class->new();
182              
183 0           for my $key (sort keys %{$hashref}) {
  0            
184 0           my $value = $hashref->{$key};
185              
186 0 0         if(!defined $value) {
    0          
    0          
187             # Skip undefined values
188 0           next;
189             } elsif(ref($value) eq 'HASH') {
190             # Nested hash - create child option list
191 0           my $childList = $class->fromHashref($value);
192 0           $optionList->addChild($key, $childList);
193             } elsif(ref($value) eq '') {
194             # Scalar value - use key prefix to determine type: i=int, s=string, h=handle/child
195 0 0         if($key =~ /^i/) {
196 0           $optionList->addInt($key, $value);
197             } else {
198 0           $optionList->addString($key, $value);
199             }
200             } else {
201 0           croak("fromHashref: unsupported value type for key '$key': " . ref($value));
202             }
203             }
204              
205 0           return $optionList;
206             }
207              
208 0     0     sub DESTROY($self) {
  0            
  0            
209             # Note: We don't free the handle here because the Pepper library
210             # manages option list memory internally. Option lists are typically
211             # freed when the instance they're associated with is freed.
212             # Only free if we explicitly own it (future enhancement)
213 0           return;
214             }
215              
216             1;
217              
218             __END__