From d627d4aa61b78fe83573aa135d2210536d00ced3 Mon Sep 17 00:00:00 2001 From: Chris Stephens Date: Tue, 15 Jan 2019 12:15:55 -0800 Subject: [PATCH] Add custom JSON generation to_json will print out a more human readable representation of the api representation. It uses api property names as json key's in order to provide more useful breadcrumbs and viewing when collapsed. --- api/product.rb | 24 ++++++++++++++++++++++++ api/resource.rb | 15 +++++++++++++++ api/type.rb | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/api/product.rb b/api/product.rb index dcca3850aab5..82a43baff263 100644 --- a/api/product.rb +++ b/api/product.rb @@ -14,6 +14,7 @@ require 'api/object' require 'google/logger' require 'compile/core' +require 'json' module Api # Repesents a product to be managed @@ -33,6 +34,23 @@ def api_name name.downcase end + def to_json(opts = nil) + json_out = {} + + instance_variables.each do |v| + if v == :@objects + json_out['@resources'] = objects.map { |o| [o.name, o] }.to_h + elsif instance_variable_get(v) == false || instance_variable_get(v).nil? + # ignore false or missing because omitting them cleans up result + # and both are the effective defaults of their types + else + json_out[v] = instance_variable_get(v) + end + end + + JSON.generate(json_out, opts) + end + # The product full name is the "display name" in string form intended for # users to read in documentation; "Google Compute Engine", "Cloud Bigtable" def product_full_name @@ -84,6 +102,12 @@ def validate check :name, type: String, allowed: ORDER, required: true end + def to_s + str = "#{name}: #{base_url}" + str += ' (default)' if default + str + end + def <=>(other) ORDER.index(name) <=> ORDER.index(other.name) if other.is_a?(Version) end diff --git a/api/resource.rb b/api/resource.rb index 5bc4994783c1..b38a3a72e1b0 100644 --- a/api/resource.rb +++ b/api/resource.rb @@ -135,6 +135,21 @@ def validate end end + def to_json(opts = nil) + # ignore fields that will contain references to parent resources + ignored_fields = %i[@__product @__parent @__resource @api_name @collection_url_response] + json_out = {} + + instance_variables.each do |v| + json_out[v] = instance_variable_get(v) unless ignored_fields.include? v + end + + json_out[:@properties] = properties.map { |p| [p.name, p] }.to_h + json_out[:@parameters] = parameters.map { |p| [p.name, p] }.to_h + + JSON.generate(json_out, opts) + end + def identity props = all_user_properties if @identity.nil? diff --git a/api/type.rb b/api/type.rb index 6cafaecee596..59be95f90b80 100644 --- a/api/type.rb +++ b/api/type.rb @@ -74,6 +74,29 @@ def validate check_conflicts end + def to_json(opts = nil) + # ignore fields that will contain references to parent resources and + # those which will be added later + ignored_fields = %i[@resource @__parent @__resource @api_name] + json_out = {} + + instance_variables.each do |v| + if v == :@conflicts && instance_variable_get(v).empty? + # ignore empty conflict arrays + elsif instance_variable_get(v) == false + # ignore false booleans as non-existence indicates falsey + elsif !ignored_fields.include? v + json_out[v] = instance_variable_get(v) + end + end + + # convert properties to a hash based on name for nested readability + json_out[:@properties] = properties&.map { |p| [p.name, p] }.to_h \ + if respond_to? 'properties' + + JSON.generate(json_out, opts) + end + def check_default_value_property return if @default_value.nil?