Module: KeyDial::Coercion::Structs::ClassMethods
- Defined in:
- lib/key_dial/coercion.rb
Instance Method Summary collapse
-
#from(_obj) ⇒ Object
Allows you to do Struct.from(obj) to instantiate a Struct using keys/values from any object intelligently.
Instance Method Details
#from(_obj) ⇒ Object
Allows you to do Struct.from(obj) to instantiate a Struct using keys/values from any object intelligently.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/key_dial/coercion.rb', line 116 def from(_obj) from_obj = _obj if !from_obj.is_a?(Struct) && !from_obj.is_a?(Hash) && !from_obj.is_a?(Array) return EMPTY if _obj == EMPTY[0] return EMPTY if _obj.nil? # For non-keyed objects, we will treat the whole object like it's a value to push into the first property of a struct from_obj = [_obj] end struct_class = self # Are we operating on a defined type of Struct? if struct_class < Struct if from_obj.is_a?(struct_class) # Has an instantiation of that type of Struct been passed in? If so, just return it return from_obj else # Get values values = [] if from_obj.is_a?(Array) # Get as many elements of array as this Struct can handle - discard the rest values = from_obj.first(struct_class.members.size) else # Not an Array, so must be another Struct or Hash struct_class.members.each { |key| if from_obj.key?(key) # If the object has this expected key, use it values << from_obj[key] else # Otherwise, fill this key with nil values << nil # Keys in the from object which don't match expected keys are discarded end } end # values now contains a value or nil for each of this class's expected keys return struct_class.new(*values) end else # Anonymous Struct new_values = from_obj.is_a?(Array) ? from_obj : from_obj.values # Iterate over the keys of the from object # (Array.keys is monkeypatched in) new_keys = from_obj.keys.each_with_index.map { |k, i| if k.respond_to?(:to_sym) && k != '' k.to_sym elsif k.respond_to?(:to_s) && !k.nil? k.to_s.to_sym else # If we can't construct a valid Struct key for this key, we discard the corresponding value new_values.delete_at(i) nil end }.reject(&:nil?) if new_keys.size > 0 # Create anonymous Struct with the specified keys and values return Struct.new(*new_keys).new(*new_values) else # Return the Empty Struct return EMPTY end end rescue return EMPTY end |