Class: Mimi::Struct
- Inherits:
-
Core::Struct
- Object
- Core::Struct
- Mimi::Struct
- Defined in:
- lib/mimi/struct.rb
Overview
A Struct that can be initialized from a Hash or a PORO.
A Struct declares its attributes and rules, which define how its attributes are mapped from input data.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
Mimi::Struct_VERSION
- DEFAULT_ATTRIBUTE_MAPPER =
Default attribute mapper
Maps value of the source attribute to the target attribute. Calculates a default value if the source attribute is not set.
-> (o, params) do source_attr_set = o.respond_to?(params[:from]) && !o.send(params[:from]).nil? if source_attr_set || !params.key?(:default) o.send(params[:from]) else # source attr is not set AND there is :default if params[:default].is_a?(Proc) call_as_proc(params[:default], o, params) # default as proc else params[:default] # default as literal value end end end
- DEFAULT_IF_FOR_OPTIONAL =
Default :if block for an optional attribute
Skips the attribute if the source attribute is not set.
-> (o, params) do o.respond_to?(params[:from]) end
Class Method Summary collapse
-
.<<(obj_or_collection) ⇒ Object
Converts a single object or collection to Struct.
-
.attribute(name, params = {}) ⇒ Object
An attribute definition.
-
.group(params, &block) ⇒ Object
Declare a group of parameters with common options.
-
.transform_attributes(source) ⇒ Hash
Transform attributes according to rules.
-
.value_to_h(value) ⇒ Object
Map value or values to Hash.
Instance Method Summary collapse
-
#attributes ⇒ Hash
Returns attributes of this Structs as a Hash.
-
#initialize(source = {}) ⇒ Struct
constructor
Creates a mapped Struct object from another object.
-
#to_h ⇒ Hash
Presents this Struct as a Hash, deeply converting nested Structs.
Constructor Details
#initialize(source = {}) ⇒ Struct
Creates a mapped Struct object from another object
52 53 54 55 56 57 58 |
# File 'lib/mimi/struct.rb', line 52 def initialize(source = {}) source = Mimi::Core::Struct.new(source) if source.is_a?(Hash) attributes = self.class.transform_attributes(source) super(attributes) rescue StandardError => e raise e.class, "Failed to construct #{self.class}: #{e}", e.backtrace end |
Class Method Details
.<<(obj_or_collection) ⇒ Object
Converts a single object or collection to Struct.
135 136 137 138 139 140 141 |
# File 'lib/mimi/struct.rb', line 135 def self.<<(obj_or_collection) if obj_or_collection.is_a?(Array) obj_or_collection.map { |o| self << o } else new(obj_or_collection) end end |
.attribute(name, params = {}) ⇒ Object
An attribute definition
Possible params:
from: <Symbol>
using: <proc,Mimi::Struct>
if: <proc>
default: <proc,Object>
optional: <true,false>
90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/mimi/struct.rb', line 90 def self.attribute(name, params = {}) name = name.to_sym raise ArgumentError, "Attribute '#{name}' is already declared" if attribute_definitions.key?(name) defaults = group_params.reduce(:merge).merge( from: name, using: DEFAULT_ATTRIBUTE_MAPPER ) params = defaults.merge(params) if params.key?(:if) && params.key?(:optional) raise ArgumentError, "Keys :if and :optional cannot be used together" end params[:if] = DEFAULT_IF_FOR_OPTIONAL if params[:optional] add_attribute_definition(name, params) end |
.group(params, &block) ⇒ Object
Declare a group of parameters with common options
E.g.
Class User < Mimi::Struct
attribute :id
attribute :type
attribute :name
group if: -> (o) { o.type == 'ADMIN' } do
attribute :admin_role
attribute :admin_domain
end
group default: -> { Time.now.utc } do
attribute :created_at
attribute :updated_at
end
end
NOTE: Not reentrable.
126 127 128 129 130 |
# File 'lib/mimi/struct.rb', line 126 def self.group(params, &block) group_params << params yield group_params.pop end |
.transform_attributes(source) ⇒ Hash
Transform attributes according to rules
185 186 187 188 189 190 191 192 193 |
# File 'lib/mimi/struct.rb', line 185 def self.transform_attributes(source) result = attribute_definitions.map do |k, params| if params[:if].is_a?(Proc) next unless call_as_proc(params[:if], source, params) end [k, transform_single_attribute(source, k, params)] end.compact.to_h result end |
.value_to_h(value) ⇒ Object
Map value or values to Hash
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/mimi/struct.rb', line 230 def self.value_to_h(value) case value when Struct value.to_h when Array value.map { |v| value_to_h(v) } else value end end |
Instance Method Details
#attributes ⇒ Hash
Returns attributes of this Structs as a Hash
74 75 76 |
# File 'lib/mimi/struct.rb', line 74 def attributes @attributes end |
#to_h ⇒ Hash
Presents this Struct as a Hash, deeply converting nested Structs
64 65 66 67 68 |
# File 'lib/mimi/struct.rb', line 64 def to_h attributes.map do |k, v| [k, self.class.value_to_h(v)] end.to_h end |