class Puppet::Pops::Serialization::FromDataConverter

Class that can process the `Data` produced by the {ToDataConverter} class and reassemble the objects that were converted.

@api public

Public Class Methods

convert(value, options = EMPTY_HASH) click to toggle source

Converts the given `Data` value according to the given options and returns the resulting `RichData`.

@param value [Data] the value to convert @param options {Symbol => <Boolean,String>} options hash @option options [Loaders::Loader] :loader the loader to use. Can be `nil` in which case the default is

determined by the {Types::TypeParser}.

@option options [Boolean] :allow_unresolved `true` to allow that rich_data hashes are kept “as is” if the

designated '__ptype' cannot be resolved. Defaults to `false`.

@return [RichData] the processed result.

@api public

   # File lib/puppet/pops/serialization/from_data_converter.rb
72 def self.convert(value, options = EMPTY_HASH)
73   new(options).convert(value)
74 end
new(options = EMPTY_HASH) click to toggle source

Creates a new instance of the processor

@param options {Symbol => Object} options hash @option options [Loaders::Loader] :loader the loader to use. Can be `nil` in which case the default is

determined by the {Types::TypeParser}.

@option options [Boolean] :allow_unresolved `true` to allow that rich_data hashes are kept “as is” if the

designated '__ptype' cannot be resolved. Defaults to `false`.

@api public

    # File lib/puppet/pops/serialization/from_data_converter.rb
 85 def initialize(options = EMPTY_HASH)
 86   @allow_unresolved = options[:allow_unresolved]
 87   @allow_unresolved = false if @allow_unresolved.nil?
 88   @loader = options[:loader]
 89 
 90   @pcore_type_procs = {
 91     PCORE_TYPE_HASH => proc do |hash, _|
 92       value = hash[PCORE_VALUE_KEY]
 93       build({}) do
 94         top = value.size
 95         idx = 0
 96         while idx < top
 97           key = without_value { convert(value[idx]) }
 98           idx += 1
 99           with(key) { convert(value[idx]) }
100           idx += 1
101         end
102       end
103     end,
104 
105     PCORE_TYPE_SENSITIVE => proc do |hash, _|
106       build(Types::PSensitiveType::Sensitive.new(convert(hash[PCORE_VALUE_KEY])))
107     end,
108 
109     PCORE_TYPE_DEFAULT => proc do |_, _|
110       build(:default)
111     end,
112 
113     PCORE_TYPE_SYMBOL => proc do |hash, _|
114       build(:"#{hash[PCORE_VALUE_KEY]}")
115     end,
116 
117     PCORE_LOCAL_REF_SYMBOL => proc do |hash, _|
118       build(JsonPath::Resolver.singleton.resolve(@root, hash[PCORE_VALUE_KEY]))
119     end
120   }
121   @pcore_type_procs.default = proc do |hash, type_value|
122     value = hash.include?(PCORE_VALUE_KEY) ? hash[PCORE_VALUE_KEY] : hash.reject { |key, _| PCORE_TYPE_KEY == key }
123     if type_value.is_a?(Hash)
124       type = without_value { convert(type_value) }
125       if type.is_a?(Hash)
126         raise SerializationError, _('Unable to deserialize type from %{type}') % { type: type } unless @allow_unresolved
127         hash
128       else
129         pcore_type_hash_to_value(type, value)
130       end
131     else
132       type = Types::TypeParser.singleton.parse(type_value, @loader)
133       if type.is_a?(Types::PTypeReferenceType)
134         unless @allow_unresolved
135           raise SerializationError, _('No implementation mapping found for Puppet Type %{type_name}') % { type_name: type_value }
136         end
137         hash
138       else
139         # not a string
140         pcore_type_hash_to_value(type, value)
141       end
142     end
143   end
144 end

Public Instance Methods

convert(value) click to toggle source

Converts the given `Data` value and returns the resulting `RichData`

@param value [Data] the value to convert @return [RichData] the processed result

@api public

    # File lib/puppet/pops/serialization/from_data_converter.rb
152 def convert(value)
153   if value.is_a?(Hash)
154     pcore_type = value[PCORE_TYPE_KEY]
155     if pcore_type && (pcore_type.is_a?(String) || pcore_type.is_a?(Hash))
156       @pcore_type_procs[pcore_type].call(value, pcore_type)
157     else
158       build({}) { value.each_pair { |key, elem| with(key) { convert(elem) }}}
159     end
160   elsif value.is_a?(Array)
161     build([]) { value.each_with_index { |elem, idx| with(idx) { convert(elem)}}}
162   else
163     build(value)
164   end
165 end

Private Instance Methods

build(value, &block) click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
193 def build(value, &block)
194   vx = Builder.new(value)
195   @current[@key] = vx unless @current.nil?
196   with_value(vx, &block) if block_given?
197   vx.resolve
198 end
build_object(builder, &block) click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
200 def build_object(builder, &block)
201   @current[@key] = builder unless @current.nil?
202   with_value(builder, &block) if block_given?
203   builder.resolve
204 end
pcore_type_hash_to_value(pcore_type, value) click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
206 def pcore_type_hash_to_value(pcore_type, value)
207   if value.is_a?(Hash)
208     # Complex object
209     if value.empty?
210       build(pcore_type.create)
211     elsif pcore_type.implementation_class.respond_to?(:_pcore_init_from_hash)
212       build_object(ObjectHashBuilder.new(pcore_type.allocate)) { value.each_pair { |key, elem| with(key) { convert(elem) } } }
213     else
214       build_object(ObjectArrayBuilder.new(pcore_type.allocate)) { value.each_pair { |key, elem| with(key) { convert(elem) } } }
215     end
216   elsif value.is_a?(String)
217     build(pcore_type.create(value))
218   else
219     raise SerializationError, _('Cannot create a %{type_name} from a %{arg_class}') %
220         { :type_name => pcore_type.name, :arg_class => value.class.name }
221   end
222 end
with(key) { || ... } click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
169 def with(key)
170   parent_key = @key
171   @key = key
172   yield
173   @key = parent_key
174 end
with_value(value) { || ... } click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
176 def with_value(value)
177   @root = value unless instance_variable_defined?(:@root)
178   parent = @current
179   @current = value
180   yield
181   @current = parent
182   value
183 end
without_value() { || ... } click to toggle source
    # File lib/puppet/pops/serialization/from_data_converter.rb
185 def without_value
186   parent = @current
187   @current = nil
188   value = yield
189   @current = parent
190   value
191 end