lib/alba.rb in alba-1.3.0 vs lib/alba.rb in alba-1.4.0

- old
+ new

@@ -1,5 +1,6 @@ +require 'json' require_relative 'alba/version' require_relative 'alba/resource' # Core module module Alba @@ -12,38 +13,51 @@ # Error class for type which is not supported class UnsupportedType < Error; end class << self attr_reader :backend, :encoder, :inferring, :_on_error, :transforming_root_key + + # Accessor for inflector, a module responsible for incflecting strings attr_accessor :inflector # Set the backend, which actually serializes object into JSON # # @param backend [#to_sym, nil] the name of the backend # Possible values are `oj`, `active_support`, `default`, `json` and nil # @return [Proc] the proc to encode object into JSON # @raise [Alba::UnsupportedBackend] if backend is not supported def backend=(backend) @backend = backend&.to_sym - set_encoder + set_encoder_from_backend end + # Set encoder, a Proc object that accepts an object and generates JSON from it + # Set backend as `:custom` which indicates no preset encoder is used + # + # @param encoder [Proc] + # @raise [ArgumentError] if given encoder is not a Proc or its arity is not one + def encoder=(encoder) + raise ArgumentError, 'Encoder must be a Proc accepting one argument' unless encoder.is_a?(Proc) && encoder.arity == 1 + + @encoder = encoder + @backend = :custom + end + # Serialize the object with inline definitions # # @param object [Object] the object to be serialized - # @param key [Symbol] + # @param key [Symbol, nil, true] DEPRECATED, use root_key instead + # @param root_key [Symbol, nil, true] # @param block [Block] resource block # @return [String] serialized JSON string # @raise [ArgumentError] if block is absent or `with` argument's type is wrong - def serialize(object, key: nil, &block) - raise ArgumentError, 'Block required' unless block + def serialize(object, key: nil, root_key: nil, &block) + warn '`key` option to `serialize` method is deprecated, use `root_key` instead.' if key + klass = block ? resource_class(&block) : infer_resource_class(object.class.name) - klass = Class.new - klass.include(Alba::Resource) - klass.class_eval(&block) resource = klass.new(object) - resource.serialize(key: key) + resource.serialize(root_key: root_key || key) end # Enable inference for key and resource name def enable_inference! begin @@ -61,10 +75,13 @@ # Set error handler # # @param [Symbol] handler # @param [Block] + # @raise [ArgumentError] if both handler and block params exist + # @raise [ArgumentError] if both handler and block params don't exist + # @return [void] def on_error(handler = nil, &block) raise ArgumentError, 'You cannot specify error handler with both Symbol and block' if handler && block raise ArgumentError, 'You must specify error handler with either Symbol or block' unless handler || block @_on_error = handler || block @@ -78,22 +95,36 @@ # Disable root key transformation def disable_root_key_transformation! @transforming_root_key = false end + # @param block [Block] resource body + # @return [Class<Alba::Resource>] resource class + def resource_class(&block) + klass = Class.new + klass.include(Alba::Resource) + klass.class_eval(&block) + klass + end + + # @param name [String] a String Alba infers resource name with + # @param nesting [String, nil] namespace Alba tries to find resource class in + # @return [Class<Alba::Resource>] resource class + def infer_resource_class(name, nesting: nil) + enable_inference! + const_parent = nesting.nil? ? Object : Object.const_get(nesting) + const_parent.const_get("#{ActiveSupport::Inflector.classify(name)}Resource") + end + private - def set_encoder + def set_encoder_from_backend @encoder = case @backend - when :oj, :oj_strict - try_oj - when :oj_rails - try_oj(mode: :rails) - when :active_support - try_active_support - when nil, :default, :json - default_encoder + when :oj, :oj_strict then try_oj + when :oj_rails then try_oj(mode: :rails) + when :active_support then try_active_support + when nil, :default, :json then default_encoder else raise Alba::UnsupportedBackend, "Unsupported backend, #{backend}" end end @@ -113,10 +144,9 @@ default_encoder end def default_encoder lambda do |hash| - require 'json' JSON.dump(hash) end end end