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