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
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
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
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
# 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
# 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
# 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
# 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
# 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
# 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