class HoneyFormat::Header
Represents a header
Public Class Methods
Instantiate a Header
@return [Header] a new instance of Header
. @param [Array<String>] header array of strings. @param converter [#call, Symbol, Hash]
header converter that implements a #call method that takes one column (string) argument OR symbol for a registered converter registry OR a hash mapped to a symbol or something that responds to #call.
@param deduplicator [#call, Symbol]
header deduplicator that implements a #call method that takes columns Array<String> argument OR symbol for a registered deduplicator registry.
@raise [HeaderError] super class of errors raised when there is a CSV
header error. @raise [MissingHeaderColumnError] raised when header is missing @example Instantiate a header with a custom converter
converter = ->(col) { col == 'username' ? 'handle' : col } header = HoneyFormat::Header.new(['name', 'username'], converter: converter) header.to_a # => ['name', 'handle']
# File lib/honey_format/matrix/header.rb, line 28 def initialize( header, converter: HoneyFormat.header_converter, deduplicator: HoneyFormat.config.header_deduplicator ) if header.nil? || header.empty? raise(Errors::MissingHeaderError, "CSV header can't be empty.") end @original_header = header self.deduplicator = deduplicator self.converter = converter @columns = build_columns(@original_header) end
Public Instance Methods
Returns columns as array. @return [Array<Symbol>] of columns.
# File lib/honey_format/matrix/header.rb, line 65 def columns @columns end
@yield [row] The given block will be passed for every column. @yieldparam [Row] a column in the CSV
header. @return [Enumerator]
If no block is given, an enumerator object will be returned.
# File lib/honey_format/matrix/header.rb, line 59 def each(&block) columns.each(&block) end
Returns true if columns contains no elements. @return [true, false] true if columns contains no elements.
# File lib/honey_format/matrix/header.rb, line 51 def empty? @columns.empty? end
Return the number of header columns @return [Integer] the number of header columns
# File lib/honey_format/matrix/header.rb, line 77 def length columns.length end
Returns the original header @return [Array<String>] the original header
# File lib/honey_format/matrix/header.rb, line 45 def original @original_header end
Returns columns as array. @return [Array<Symbol>] of columns.
# File lib/honey_format/matrix/header.rb, line 71 def to_a columns end
Header
as CSV-string @return [String] CSV-string representation.
# File lib/honey_format/matrix/header.rb, line 84 def to_csv(columns: nil) attributes = if columns self.columns & columns.map(&:to_sym) else self.columns end ::CSV.generate_line(attributes) end
Private Instance Methods
Convert original header @param [Array<String>] header the original header @return [Array<String>] converted columns
# File lib/honey_format/matrix/header.rb, line 128 def build_columns(header) columns = header.each_with_index.map do |header_column, index| convert_column(header_column, index).tap do |column| maybe_raise_missing_column!(column) end end @deduplicator.call(columns) end
# File lib/honey_format/matrix/header.rb, line 188 def call_column_builder(callable, value, index) return callable.call if callable_arity(callable).zero? return callable.call(value) if callable_arity(callable) == 1 callable.call(value, index) end
Returns the callable object method arity @param [#arity, call] callable thing that responds to call and maybe arity @return [Integer] the method arity
# File lib/honey_format/matrix/header.rb, line 149 def callable_arity(callable) # procs and lambdas respond to #arity return callable.arity if callable.respond_to?(:arity) callable.method(:call).arity end
Convert the column value @param [String, Symbol] column the CSV
header column value @param [Integer] index the CSV
header column index @return [Symbol] the converted column
# File lib/honey_format/matrix/header.rb, line 142 def convert_column(column, index) call_column_builder(@converter, column, index)&.to_sym end
Set the header converter @param [Hash, Symbol, call] symbol to known converter, object that responds to call or Hash @return [nil]
# File lib/honey_format/matrix/header.rb, line 99 def converter=(object) if object.is_a?(Symbol) @converter = HoneyFormat.converter_registry[object] return end if object.is_a?(Hash) @converter = hash_converter(object) return end @converter = object end
Set the header deduplicator @param [Symbol, call] symbol to known deduplicator or object that responds to call @return [nil]
# File lib/honey_format/matrix/header.rb, line 116 def deduplicator=(object) if object.is_a?(Symbol) @deduplicator = HoneyFormat.header_deduplicator_registry[object] return end @deduplicator = object end
# File lib/honey_format/matrix/header.rb, line 170 def hash_converter(hash) lambda { |value, index| # support strings and symbol keys interchangeably column = hash.fetch(value) do key = value.respond_to?(:to_sym) ? value.to_sym : value # if column is unmapped use the default header converter hash.fetch(key) { HoneyFormat.header_converter.call(value, index) } end # The hash can contain mixed values, Symbol and procs if column.respond_to?(:call) column = call_column_builder(column, value, index) end column&.to_sym } end
Raises an error if header column is missing/empty @param [Object] column the CSV
header column @raise [Errors::MissingHeaderColumnError]
# File lib/honey_format/matrix/header.rb, line 159 def maybe_raise_missing_column!(column) return if column && !column.empty? parts = [ "CSV header column can't be nil or empty!", 'When you pass your own converter make sure that it never returns nil or an empty string.', # rubocop:disable Metrics/LineLength 'Instead generate unique columns names.', ] raise(Errors::MissingHeaderColumnError, parts.join(' ')) end