lib/hcloud/entry_loader.rb in hcloud-1.0.3 vs lib/hcloud/entry_loader.rb in hcloud-1.1.0

- old
+ new

@@ -72,38 +72,61 @@ ancestors.reverse.find { |const| const.include?(Hcloud::EntryLoader) } end def from_response(response, autoload_action: nil) attributes = response.resource_attributes - action = response.parsed_json[:action] if autoload_action + + action_resp = _try_load_action(response) if autoload_action + return action_resp unless attributes || action_resp.nil? + client = response.context.client if attributes.is_a?(Array) - results = attributes.map { |item| new(item).tap { |entity| entity.response = response } } + results = attributes.map do |item| + new(client, item).tap do |entity| + entity.response = response + end + end results.tap { |ary| ary.extend(Collection) }.response = response return results end - return Action.new(client, action) if attributes.nil? && action - return new(attributes).tap { |entity| entity.response = response } if action.nil? + if action_resp.nil? + return new(client, attributes).tap { |entity| entity.response = response } + end [ - Action.new(client, action), - new(attributes).tap { |entity| entity.response = response } + action_resp, + new(client, attributes).tap { |entity| entity.response = response } ] end - end - attr_accessor :response + def _try_load_action(response) + # some API endpoints return a list of actions (e.g. firewall action + # apply_to_resources), some a single action (e.g. server action + # attach_iso) + actions = response.parsed_json[:actions] + action = response.parsed_json[:action] - def initialize(client = nil, kwargs = {}) - if client.is_a?(Hash) - kwargs = client - client = nil + client = response.context.client + + if actions + return actions.map do |act| + Action.new(client, act) + end + elsif action + return Action.new(client, action) + end + + nil end + end + attr_accessor :response + + def initialize(client = nil, resource = {}) @client = client - _load(kwargs) + _load(resource) end def inspect "#<#{self.class.name}:0x#{__id__.to_s(16)} #{_attributes.inspect}>" end @@ -177,11 +200,14 @@ def _update_attribute(key, value) _attributes[key] = value instance_variable_set("@#{key}", value) end + # rubocop: disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize def _load(resource) + return if resource.nil? + @_attributes = {}.with_indifferent_access resource.each do |key, value| definition = self.class.schema[key] @@ -193,10 +219,32 @@ if definition.is_a?(Class) && definition.include?(EntryLoader) _update_attribute(key, value ? definition.new(client, value) : nil) next end + # if schema definition is [Class] + if definition.is_a?(Array) && definition.first.include?(EntryLoader) + + # just set attribute to an empty array if value is no array or empty + if !value.is_a?(Array) || value.empty? + _update_attribute(key, []) + next + end + + if value.first.is_a?(Integer) + # If value is an integer, this is the id of an object which's class can be + # retreived from definition. Load a future object that can on access retreive the + # data from the api and convert it to a proper object. + _update_attribute(key, value.map { |id| Future.new(client, definition.first, id) }) + else + # Otherwise the value *is* the content of the object + _update_attribute(key, value.map { |item| definition.first.new(client, item) }) + end + next + end + _update_attribute(key, value.is_a?(Hash) ? value.with_indifferent_access : value) end end + # rubocop: enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize end end