Skip to content

Commit 95cf780

Browse files
authored
Merge pull request #1259 from david22swan/feat/main/add_function_parsepson
(FEAT) Add function parsepson
2 parents 1306ed5 + 0f032a9 commit 95cf780

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

REFERENCE.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ true boolean.
140140
Puppet structure
141141
* [`parsejson`](#parsejson): This function accepts JSON as a string and converts it into the correct
142142
Puppet structure.
143+
* [`parsepson`](#parsepson): This function accepts PSON, a Puppet variant of JSON, as a string and
144+
converts it into the correct Puppet structure.
143145
* [`parseyaml`](#parseyaml): This function accepts YAML as a string and converts it into the correct
144146
Puppet structure.
145147
* [`pick`](#pick): This function will return
@@ -3939,6 +3941,53 @@ Type: Ruby 3.x API
39393941
The optional second argument can be used to pass a default value that will
39403942
be returned if the parsing of YAML string have failed.
39413943

3944+
### <a name="parsepson"></a>`parsepson`
3945+
3946+
Type: Ruby 4.x API
3947+
3948+
This function accepts PSON as a string and converts it into the correct
3949+
Puppet structure
3950+
3951+
#### Examples
3952+
3953+
##### How to parse pson
3954+
3955+
```puppet
3956+
$data = parsepson('{"a":"1","b":"2"}')
3957+
```
3958+
3959+
For more information on PSON please see the following link:
3960+
https://puppet.com/docs/puppet/7/http_api/pson.html
3961+
3962+
#### `parsepson(String $pson_string, Optional[Any] $default)`
3963+
3964+
The parseson function.
3965+
3966+
Returns: `Data`
3967+
3968+
##### Examples
3969+
3970+
###### How to parse pson
3971+
3972+
```puppet
3973+
$data = parsepson('{"a":"1","b":"2"}')
3974+
```
3975+
3976+
For more information on PSON please see the following link:
3977+
https://puppet.com/docs/puppet/7/http_api/pson.html
3978+
3979+
##### `pson_string`
3980+
3981+
Data type: `String[1]`
3982+
3983+
A valid PSON string
3984+
3985+
##### `default`
3986+
3987+
Data type: `Optional[Any]`
3988+
3989+
An optional default to return if parsing the pson_string fails
3990+
39423991
#### `parseyaml()`
39433992

39443993
> *Note:*

lib/puppet/functions/parsepson.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
# @summary
4+
# This function accepts PSON, a Puppet variant of JSON, as a string and converts
5+
# it into the correct Puppet structure
6+
#
7+
# @example How to parse pson
8+
# $data = parsepson('{"a":"1","b":"2"}')
9+
#
10+
# For more information on PSON please see the following link:
11+
# https://puppet.com/docs/puppet/7/http_api/pson.html
12+
#
13+
Puppet::Functions.create_function(:parsepson) do
14+
# @param pson_string A valid PSON string
15+
# @param default An optional default to return if parsing the pson_string fails
16+
# @return [Data]
17+
dispatch :parsepson do
18+
param 'String[1]', :pson_string
19+
optional_param 'Any', :default
20+
end
21+
22+
def parsepson(pson_string, default = :no_default_provided)
23+
PSON.load(pson_string)
24+
rescue StandardError => err
25+
Puppet.debug("Parsing PSON failed with error: #{err.message}")
26+
raise err if default == :no_default_provided
27+
default
28+
end
29+
end

spec/functions/parsepson_spec.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'parsepson' do
6+
it 'exists' do
7+
is_expected.not_to eq(nil)
8+
end
9+
10+
it 'raises an error if called without any arguments' do
11+
is_expected.to run.with_params
12+
.and_raise_error(%r{'parsepson' expects between 1 and 2 arguments, got none}i)
13+
end
14+
15+
context 'with correct PSON data' do
16+
it 'is able to parse PSON data with a Hash' do
17+
is_expected.to run.with_params('{"a":"1","b":"2"}')
18+
.and_return('a' => '1', 'b' => '2')
19+
end
20+
21+
it 'is able to parse PSON data with an Array' do
22+
is_expected.to run.with_params('["a","b","c"]')
23+
.and_return(['a', 'b', 'c'])
24+
end
25+
26+
it 'is able to parse empty PSON values' do
27+
actual_array = ['[]', '{}']
28+
expected = [[], {}]
29+
actual_array.each_with_index do |actual, index|
30+
is_expected.to run.with_params(actual).and_return(expected[index])
31+
end
32+
end
33+
34+
it 'is able to parse PSON data with a mixed structure' do
35+
is_expected.to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}')
36+
.and_return('a' => '1', 'b' => 2, 'c' => { 'd' => [true, false] })
37+
end
38+
39+
it 'is able to parse PSON data with a UTF8 and double byte characters' do
40+
is_expected.to run.with_params('{"×":"これ","ý":"記号","です":{"©":["Á","ß"]}}')
41+
.and_return('×' => 'これ', 'ý' => '記号', 'です' => { '©' => ['Á', 'ß'] })
42+
end
43+
44+
it 'does not return the default value if the data was parsed correctly' do
45+
is_expected.to run.with_params('{"a":"1"}', 'default_value')
46+
.and_return('a' => '1')
47+
end
48+
end
49+
50+
context 'with incorrect PSON data' do
51+
it 'raises an error with invalid PSON and no default' do
52+
is_expected.to run.with_params('invalid')
53+
.and_raise_error(PSON::ParserError)
54+
end
55+
56+
it 'returns the default value for an invalid PSON and a given default' do
57+
is_expected.to run.with_params('invalid', 'default_value')
58+
.and_return('default_value')
59+
end
60+
61+
it 'supports a structure for a default value' do
62+
is_expected.to run.with_params('invalid', 'a' => '1')
63+
.and_return('a' => '1')
64+
end
65+
end
66+
end

0 commit comments

Comments
 (0)