lib/bumblebee/column.rb in bumblebee-2.1.0 vs lib/bumblebee/column.rb in bumblebee-3.0.0
- old
+ new
@@ -6,85 +6,63 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
#
module Bumblebee
- # This is main piece of logic that defines a column which can go from objects to csv cell values
- # and csv rows to objects.
+ # This is main piece of logic that defines a column which can go
+ # from objects to csv cell values and csv rows to objects.
class Column
- acts_as_hashable
+ attr_reader :header,
+ :property,
+ :through,
+ :to_csv,
+ :to_object
- attr_reader :field,
- :to_object,
- :header,
- :to_csv
+ def initialize(
+ header,
+ property: nil,
+ through: [],
+ to_csv: nil,
+ to_object: nil
+ )
+ raise ArgumentError, 'header is required' if header.to_s.empty?
- def initialize(field:, header: nil, to_csv: nil, to_object: nil)
- raise ArgumentError, 'field is required' unless field
+ @header = header.to_s
+ @property = property || @header
+ @through = Array(through)
+ @to_csv = ::Bumblebee::Mutator.new(to_csv)
+ @to_object = ::Bumblebee::Mutator.new(to_object)
- @field = field
- @header = make_header(header || field)
- @to_csv = Array(to_csv || field)
- @to_object = Array(to_object || @header)
+ freeze
end
- # Take a object and convert to a value.
- def object_to_csv(object)
- val = object
+ # Extract from object and set on hash
+ def csv_set(data_object, hash)
+ value = extract(traverse(data_object), property)
- # Iterate over keys until we reach a nil or the end of keys.
- to_csv.each do |f|
- # short-circuit out of the extract method
- return nil unless val
-
- val = single_extract(val, f)
- end
-
- val
+ to_csv.set(hash, header, value)
end
- def csv_to_object(csv_hash)
- return nil unless csv_hash
+ def object_set(csv_object, hash)
+ pointer = build(hash)
+ value = csv_object[header]
- value = csv_hash
+ to_object.set(pointer, property, value)
- to_object.each do |f|
- value = single_extract(value, f)
- end
-
- hash = {}
- hash.tap { hash[field] = value }
+ hash
end
private
- # Loop through all values, contcatenating their string equivalent with an underscore.
- # Since we allow procs, but we want deterministic headers, we will simply transform
- # theem to _proc_. This is not perfect and could create naming clashes, but it really
- # should not be. You should really leave proc's out of header and field.
- def make_header(value)
- Array(value).map do |v|
- if v.is_a?(Proc)
- 'proc'
- else
- v.to_s
- end
- end.join('_')
+ def traverse(object)
+ ::Bumblebee::ObjectInterface.traverse(object, through)
end
- # Take an object and attempt to extract a value from it.
- # First, see if the key is a proc, if so, then delegate to the proc.
- # Next, see if the object responds to the key, if so, then call it.
- # Lastly, see if it responds to brackets, if so, then call the brackets method sending
- # in the key.
- # Finally if all else fails, return nil.
- def single_extract(object, key)
- if key.is_a?(Proc)
- key.call(object)
- elsif object.respond_to?(key)
- object.send(key)
- elsif object.respond_to?(:[])
- object[key]
- end
+ def extract(object, key)
+ ::Bumblebee::ObjectInterface.get(object, key)
+ end
+
+ def build(object)
+ ::Bumblebee::ObjectInterface.build(object, through)
end
end
end