lib/bumblebee/template.rb in bumblebee-3.0.1 vs lib/bumblebee/template.rb in bumblebee-3.1.0.pre.alpha
- old
+ new
@@ -11,18 +11,18 @@
# Wraps up columns and provides to main methods:
# generate_csv: take in an array of objects and return a string (CSV contents)
# parse_csv: take in a string and return an array of hashes
class Template
extend Forwardable
- extend ::Bumblebee::ColumnDsl
+ extend ColumnDsl
def_delegators :column_set, :headers, :columns
attr_reader :object_class
def initialize(columns: nil, object_class: Hash, &block)
- @column_set = ::Bumblebee::ColumnSet.new(self.class.all_columns)
+ @column_set = ColumnSet.new(self.class.all_columns)
@object_class = object_class
column_set.add(columns)
return unless block_given?
@@ -38,35 +38,62 @@
column_set.column(header, opts)
self
end
- def generate(objects, options = {})
- objects = objects.is_a?(Hash) ? [objects] : Array(objects)
+ BOM = :bom
+ UTF8_BOM = "\xEF\xBB\xBF"
- write_options = options.merge(headers: headers, write_headers: true)
+ CUSTOM_OPTIONS = [
+ BOM
+ ].to_set.freeze
- CSV.generate(write_options) do |csv|
+ def generate(objects, options = {})
+ objects = array(objects)
+ options = parse_options(options)
+ prefix = options.bom ? UTF8_BOM : ''
+
+ prefix + CSV.generate(options.ruby_csv_options) do |csv|
objects.each do |object|
csv << columns.each_with_object({}) do |column, hash|
column.csv_set(object, hash)
end
end
end
end
def parse(string, options = {})
- csv = CSV.new(string, options.merge(headers: true))
+ string_without_bom = string.sub(UTF8_BOM, '')
+ csv = CSV.new(string_without_bom, options.merge(headers: true))
+
csv.to_a.map do |row|
# Build up a hash using the column one at a time
columns.each_with_object(object_class.new) do |column, object|
column.object_set(row, object)
end
end
end
private
+ Options = Struct.new(:ruby_csv_options, :bom)
+
+ private_constant :Options
+
attr_reader :column_set
+
+ def array(objects)
+ objects.is_a?(Hash) ? [objects] : Array(objects)
+ end
+
+ def parse_options(options)
+ options = (options || {}).symbolize_keys
+ bom = options[BOM] || false
+
+ ruby_csv_options = options.merge(headers: headers, write_headers: true)
+ .reject { |k| CUSTOM_OPTIONS.include?(k) }
+
+ Options.new(ruby_csv_options, bom)
+ end
end
end