# frozen_string_literal: true module JSONAPI class Formatter class << self def format(arg) arg.to_s end def unformat(arg) arg end def cached return FormatterWrapperCache.new(self) end def uncached return self end def formatter_for(format) "#{format.to_s.camelize}Formatter".safe_constantize end end end class KeyFormatter < Formatter class << self def format(key) super end def unformat(formatted_key) super end end end class RouteFormatter < Formatter class << self def format(route) super end def unformat(formatted_route) super end end end class ValueFormatter < Formatter class << self def format(raw_value) super(raw_value) end def unformat(value) super(value) end def value_formatter_for(type) "#{type.to_s.camelize}ValueFormatter".safe_constantize end end end # Warning: Not thread-safe. Wrap in ThreadLocalVar as needed. class FormatterWrapperCache attr_reader :formatter_klass def initialize(formatter_klass) @formatter_klass = formatter_klass @format_cache = NaiveCache.new{|arg| formatter_klass.format(arg) } @unformat_cache = NaiveCache.new{|arg| formatter_klass.unformat(arg) } end def format(arg) @format_cache.get(arg) end def unformat(arg) @unformat_cache.get(arg) end def cached self end def uncached return @formatter_klass end end end class UnderscoredKeyFormatter < JSONAPI::KeyFormatter end class CamelizedKeyFormatter < JSONAPI::KeyFormatter class << self def format(key) super.camelize(:lower) end def unformat(formatted_key) formatted_key.to_s.underscore end end end class DasherizedKeyFormatter < JSONAPI::KeyFormatter class << self def format(_key) super.underscore.dasherize end def unformat(formatted_key) formatted_key.to_s.underscore end end end class DefaultValueFormatter < JSONAPI::ValueFormatter class << self def format(raw_value) case raw_value when Date, Time, DateTime, ActiveSupport::TimeWithZone, BigDecimal # Use the as_json methods added to various base classes by ActiveSupport return raw_value.as_json else return raw_value end end end end class IdValueFormatter < JSONAPI::ValueFormatter class << self def format(raw_value) return if raw_value.nil? raw_value.to_s end end end class UnderscoredRouteFormatter < JSONAPI::RouteFormatter end class CamelizedRouteFormatter < JSONAPI::RouteFormatter class << self def format(_route) super.camelize(:lower) end def unformat(formatted_route) formatted_route.to_s.underscore end end end class DasherizedRouteFormatter < JSONAPI::RouteFormatter class << self def format(_route) super.dasherize end def unformat(formatted_route) formatted_route.to_s.underscore end end end