class CinnamonSerial::Resolver
Class that allows an engineer to specify what to do about mapping a key for a serializer.
Attributes
as[RW]
blank[RW]
false_alias[RW]
for[RW]
manual[RW]
mask[RW]
mask_char[RW]
mask_len[RW]
method[RW]
null[RW]
percent[RW]
present[RW]
through[RW]
transform[RW]
true_alias[RW]
Public Class Methods
new(options = {})
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 29 def initialize(options = {}) @option_keys = options.keys.map(&:to_s).to_set options.each do |key, value| raise ArgumentError, "Illegal option: #{key}" unless respond_to?(key) send("#{key}=", value) end end
Public Instance Methods
resolve(presenter, key)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 39 def resolve(presenter, key) raise ArgumentError, 'Presenter is required' unless presenter return if manual # Get the value value = resolve_value(presenter, key) # Transform the value value = resolve_transform(presenter, key, value) value = resolve_alias(value) value = resolve_as(presenter, value) # Format the value value = resolve_percent(value) resolve_mask(value) end
Private Instance Methods
as_class_constant()
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 157 def as_class_constant return nil unless as class_name = as_class_name # If we have a peer dependency for ActiveSupport then lets use it. if class_name.is_a?(String) && class_name.respond_to?(:constantize) class_name.constantize elsif class_name.is_a?(String) Object.const_get(class_name) else class_name end end
as_class_name()
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 142 def as_class_name return nil unless as non_constant_types = %w[String Symbol] # If we have a peer dependency for ActiveSupport then lets use it. if non_constant_types.include?(as.class.name) && as.to_s.respond_to?(:classify) as.to_s.classify elsif non_constant_types.include?(as.class.name) as.to_s else as end end
resolve_alias(value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 87 def resolve_alias(value) if @option_keys.include?('true_alias') && value.is_a?(TrueClass) true_alias elsif @option_keys.include?('false_alias') && value.is_a?(FalseClass) false_alias elsif @option_keys.include?('null') && value.nil? null elsif @option_keys.include?('blank') && Formatting.blank?(value) blank elsif @option_keys.include?('present') && Formatting.present?(value) present else value end end
resolve_as(presenter, value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 111 def resolve_as(presenter, value) return value unless as return nil unless value class_constant = as_class_constant # If we already serialized this type, lets not do it again. # This will prevent endless cycles / loops. return nil if presenter.klasses.include?(class_constant.to_s) new_klasses = presenter.klasses + Set[class_constant.to_s] value = value_to_array_or_scalar(value) if value.is_a?(Array) value.map { |v| class_constant.new(v, presenter.opts, new_klasses) } else class_constant.new(value, presenter.opts, new_klasses) end end
resolve_mask(value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 103 def resolve_mask(value) mask ? Formatting.mask(value, mask_len || 4, mask_char || 'X') : value end
resolve_percent(value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 107 def resolve_percent(value) percent ? Formatting.percent(value) : value end
resolve_transform(presenter, key, value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 80 def resolve_transform(presenter, key, value) return presenter.send(key, value) if transform.is_a?(TrueClass) return presenter.send(transform, value) if Formatting.present?(transform) value end
resolve_value(presenter, key)
click to toggle source
(method) and (for/through) are mutually exlusive use-cases. Example: you would never use for and method.
# File lib/cinnamon_serial/resolver.rb, line 61 def resolve_value(presenter, key) # If you pass in something that is not true boolean value then use that as a method name # to call on the presenter. return presenter.send(key) if method.is_a?(TrueClass) return presenter.send(method) if method.to_s.length.positive? # User for/through model_key = self.for || key model = presenter.obj Array(through).each do |association| model = model.respond_to?(association) ? model.send(association) : nil break unless model end model&.respond_to?(model_key) ? model.send(model_key) : nil end
value_to_array_or_scalar(value)
click to toggle source
# File lib/cinnamon_serial/resolver.rb, line 132 def value_to_array_or_scalar(value) # We do not want to create a hard dependency on ActiveRecord/Rails in this gem, # but we can still create a soft dependency in case it was included as a peer. if Module.const_defined?('ActiveRecord') && value.is_a?(ActiveRecord::Relation) value.to_a else value end end