Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ true boolean.
Puppet structure
* [`parsejson`](#parsejson): This function accepts JSON as a string and converts it into the correct
Puppet structure.
* [`parsepson`](#parsepson): This function accepts PSON, a Puppet variant of JSON, as a string and
converts it into the correct Puppet structure.
* [`parseyaml`](#parseyaml): This function accepts YAML as a string and converts it into the correct
Puppet structure.
* [`pick`](#pick): This function will return
Expand Down Expand Up @@ -3939,6 +3941,53 @@ Type: Ruby 3.x API
The optional second argument can be used to pass a default value that will
be returned if the parsing of YAML string have failed.

### <a name="parsepson"></a>`parsepson`

Type: Ruby 4.x API

This function accepts PSON as a string and converts it into the correct
Puppet structure

#### Examples

##### How to parse pson

```puppet
$data = parsepson('{"a":"1","b":"2"}')
```

For more information on PSON please see the following link:
https://puppet.com/docs/puppet/7/http_api/pson.html

#### `parsepson(String $pson_string, Optional[Any] $default)`

The parseson function.

Returns: `Data`

##### Examples

###### How to parse pson

```puppet
$data = parsepson('{"a":"1","b":"2"}')
```

For more information on PSON please see the following link:
https://puppet.com/docs/puppet/7/http_api/pson.html

##### `pson_string`

Data type: `String[1]`

A valid PSON string

##### `default`

Data type: `Optional[Any]`

An optional default to return if parsing the pson_string fails

#### `parseyaml()`

> *Note:*
Expand Down
29 changes: 29 additions & 0 deletions lib/puppet/functions/parsepson.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

# @summary
# This function accepts PSON, a Puppet variant of JSON, as a string and converts
# it into the correct Puppet structure
#
# @example How to parse pson
# $data = parsepson('{"a":"1","b":"2"}')
#
# For more information on PSON please see the following link:
# https://puppet.com/docs/puppet/7/http_api/pson.html
#
Puppet::Functions.create_function(:parsepson) do
# @param pson_string A valid PSON string
# @param default An optional default to return if parsing the pson_string fails
# @return [Data]
dispatch :parsepson do
param 'String[1]', :pson_string
optional_param 'Any', :default
end

def parsepson(pson_string, default = :no_default_provided)
PSON.load(pson_string)
rescue StandardError => err
Puppet.debug("Parsing PSON failed with error: #{err.message}")
raise err if default == :no_default_provided
default
end
end
66 changes: 66 additions & 0 deletions spec/functions/parsepson_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'parsepson' do
it 'exists' do
is_expected.not_to eq(nil)
end

it 'raises an error if called without any arguments' do
is_expected.to run.with_params
.and_raise_error(%r{'parsepson' expects between 1 and 2 arguments, got none}i)
end

context 'with correct PSON data' do
it 'is able to parse PSON data with a Hash' do
is_expected.to run.with_params('{"a":"1","b":"2"}')
.and_return('a' => '1', 'b' => '2')
end

it 'is able to parse PSON data with an Array' do
is_expected.to run.with_params('["a","b","c"]')
.and_return(['a', 'b', 'c'])
end

it 'is able to parse empty PSON values' do
actual_array = ['[]', '{}']
expected = [[], {}]
actual_array.each_with_index do |actual, index|
is_expected.to run.with_params(actual).and_return(expected[index])
end
end

it 'is able to parse PSON data with a mixed structure' do
is_expected.to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}')
.and_return('a' => '1', 'b' => 2, 'c' => { 'd' => [true, false] })
end

it 'is able to parse PSON data with a UTF8 and double byte characters' do
is_expected.to run.with_params('{"×":"これ","ý":"記号","です":{"©":["Á","ß"]}}')
.and_return('×' => 'これ', 'ý' => '記号', 'です' => { '©' => ['Á', 'ß'] })
end

it 'does not return the default value if the data was parsed correctly' do
is_expected.to run.with_params('{"a":"1"}', 'default_value')
.and_return('a' => '1')
end
end

context 'with incorrect PSON data' do
it 'raises an error with invalid PSON and no default' do
is_expected.to run.with_params('invalid')
.and_raise_error(PSON::ParserError)
end

it 'returns the default value for an invalid PSON and a given default' do
is_expected.to run.with_params('invalid', 'default_value')
.and_return('default_value')
end

it 'supports a structure for a default value' do
is_expected.to run.with_params('invalid', 'a' => '1')
.and_return('a' => '1')
end
end
end