module JSONConvertible::ClassMethods
add these as class methods
Public Instance Methods
class method This method is intended to be overridden by any class that implements `JSONConvertible` and need to use a custom mapping of the attributes to JSON keys.
@example def self.attribute_key_name_map return { :@some_key => "some_key_in_json" } end
@return [Hash] of mapping properties to keys in the JSON
# File lib/json_convertible.rb, line 116 def attribute_key_name_map return {} end
class method This method is intended to be overridden by any class that implements `JSONConvertible` and need to encode the result of the class attributes in a certain format into the JSON.
@example def self.attribute_name_to_json_proc_map timestamp_to_json_proc = proc { |timestamp| timestamp.strftime('%Q') } return { :@timestamp => timestamp_to_json_proc } end
@return [Hash] of properties and procs formatting to JSON
# File lib/json_convertible.rb, line 136 def attribute_name_to_json_proc_map return {} end
class method This method is intended to be overridden by any class that implements `JSONConvertible` and need to provide the encoder information about which types are each attribute of the class.
@example def attribute_to_type_map return { :@string_attribute => String, :@custom_class_attribute => CustomClass } end
@return [Hash] of properties and their types
# File lib/json_convertible.rb, line 174 def attribute_to_type_map return {} end
# File lib/json_convertible.rb, line 76 def from_json!(json_object) instance, json_object = _initialize_using!(json_object) json_object.each do |var, val| # If we encounter with a value that is represented by an array, iterate over it. if val.kind_of?(Array) # For each of the objects in the array, we call the protected method to build the object array. array_property = [] array_name = nil val.each do |array_val| array_name, this_instance = _from_json!(var, array_val, is_iterable: true) array_property << this_instance end if array_name.nil? if attribute_key_name_map.key(var) array_name = attribute_key_name_map.key(var).to_sym else array_name = "@#{var}".to_sym end end instance.instance_variable_set(array_name, array_property) else var_name, var_value = _from_json!(var, val) instance.instance_variable_set(var_name, var_value) end end return instance end
class method This method is intended to be overridden by any class that implements `JSONConvertible` and need to decode the JSON values back to the original types of the class attributes.
@example def self.json_to_attribute_name_proc_map json_to_timestamp_proc = proc { |json| Time.at(json.to_i) } return { :@timestamp => json_to_timestamp_proc } end
@return [Hash] of properties and procs formatting from JSON
# File lib/json_convertible.rb, line 156 def json_to_attribute_name_proc_map return {} end
class method This method is intended to be overridden by any class that implements `JSONConvertible` and need to provide a custom mapping for a enumerable property in the JSON.
@param enumerable_property_name [Any] the property name of the object. @param current_json_object [Hash] the hash object of `enumerable_property_name` for a given iteration step.
@example def map_enumerable_type(enumerable_property_name: nil, current_json_object: nil) if enumerable_property_name == :@job_triggers JobTrigger needs a factory method that reads `json[:type]` and instantiates the proper type return FastlaneCI::JobTrigger.create(json: current_json_object) end end
@return [Any] object in the array by the given `property_name` and `json_object`.
# File lib/json_convertible.rb, line 196 def map_enumerable_type(enumerable_property_name: nil, current_json_object: nil) return nil end
Protected Instance Methods
# File lib/json_convertible.rb, line 202 def _from_json!(var, val, is_iterable: false) if attribute_key_name_map.key(var) var_name = attribute_key_name_map.key(var).to_sym else var_name = "@#{var}".to_sym end if json_to_attribute_name_proc_map.key?(var_name) var_value = json_to_attribute_name_proc_map[var_name].call(val) else var_value = val end if attribute_to_type_map.key?(var_name) if attribute_to_type_map[var_name].include?(JSONConvertible) # classes that include `JSONConvertible` take precedence over custom mapping. var_value = attribute_to_type_map[var_name].from_json!(val) else raise TypeError, "#{var_name} does not implement `FastlaneCI::JSONConvertible`" end elsif is_iterable # This is only intended for array properties, it passes the final variable name and a single object of # the variable array. Expects to return and object. var_value = map_enumerable_type(enumerable_property_name: var_name, current_json_object: val) end return var_name, var_value end
# File lib/json_convertible.rb, line 231 def _initialize_using!(json_object) instance = allocate required_init_params = instance.method(:initialize).parameters .select { |arg| arg[0] == :keyreq } .map(&:last) unless (required_init_params - json_object.keys).empty? raise JSONConvertibleError.new, "Required initialization parameters not found in the object: #{json_object}" end init_params_hash = json_object.select { |key, _value| required_init_params.include?(key) } if instance.method(:initialize).parameters.empty? instance.send(:initialize) else instance.send(:initialize, init_params_hash) end clean_json_object = json_object.reject { |key| required_init_params.include?(key) } return instance, clean_json_object end