lib/csv_decision/dictionary.rb in csv_decision-0.0.9 vs lib/csv_decision/dictionary.rb in csv_decision-0.1.0
- old
+ new
@@ -24,13 +24,11 @@
def ins?
%i[in guard].member?(type) ? true : false
end
end
- # TODO: implement all anonymous column types
- # COLUMN_TYPE_ANONYMOUS = Set.new(%i[path if guard]).freeze
- # These column types do not need a name
+ # These column types do not need a name.
COLUMN_TYPE_ANONYMOUS = Set.new(%i[guard if]).freeze
private_constant :COLUMN_TYPE_ANONYMOUS
# Classify and build a dictionary of all input and output columns by
# parsing the header row.
@@ -40,31 +38,25 @@
def self.build(header:, dictionary:)
header.each_with_index do |cell, index|
dictionary = parse_cell(cell: cell, index: index, dictionary: dictionary)
end
- validate(dictionary)
- end
-
- def self.validate(dictionary)
- dictionary.outs.each_pair do |col, column|
- validate_out(dictionary: dictionary, column_name: column.name, col: col)
- end
-
dictionary
end
- private_class_method :validate
- def self.validate_out(dictionary:, column_name:, col:)
- if dictionary.ins.any? { |_, column| column_name == column.name }
- raise CellValidationError, "output column name '#{column_name}' is also an input column"
- end
+ # Add a new symbol to the dictionary of named input and output columns.
+ #
+ # @param columns [{Symbol=>Symbol}] Hash of column names with key values :in or :out.
+ # @param name [Symbol] Symbolized column name.
+ # @param out [false, Index] False if an input column, otherwise the index of the output column.
+ # @return [{Symbol=>Symbol}] Column dictionary updated with the new name.
+ def self.add_name(columns:, name:, out: false)
+ validate_name(columns: columns, name: name, out: out)
- return unless dictionary.outs.any? { |key, column| column_name == column.name && col != key }
- raise CellValidationError, "output column name '#{column_name}' is duplicated"
+ columns[name] = out ? out : :in
+ columns
end
- private_class_method :validate_out
def self.validate_column(cell:, index:)
match = Header::COLUMN_TYPE.match(cell)
raise CellValidationError, 'column name is not well formed' unless match
@@ -122,23 +114,56 @@
# Columns::Default.new(entry.name, nil, default_if(type))
#
# # Treat set: as an in: column
# dictionary.ins[index] = entry
- when :in, :guard
+ when :in
+ add_name(columns: dictionary.columns, name: entry.name)
dictionary.ins[index] = entry
+ # A guard column is still added to the ins hash for parsing as an input column.
+ when :guard
+ dictionary.ins[index] = entry
+
when :out
+ add_name(columns: dictionary.columns, name: entry.name, out: index)
dictionary.outs[index] = entry
+ # Add an if: column to both the +outs+ hash for output column parsing, and also
+ # a specialized +ifs+ hash used for evaluating them for row filtering.
when :if
dictionary.outs[index] = entry
dictionary.ifs[index] = entry
end
dictionary
end
private_class_method :dictionary_entry
+
+ def self.validate_name(columns:, name:, out:)
+ return unless (in_out = columns[name])
+
+ return validate_out_name(in_out: in_out, name: name) if out
+ validate_in_name(in_out: in_out, name: name)
+ end
+ private_class_method :validate_name
+
+ def self.validate_out_name(in_out:, name:)
+ if in_out == :in
+ raise CellValidationError, "output column name '#{name}' is also an input column"
+ end
+
+ raise CellValidationError, "output column name '#{name}' is duplicated"
+ end
+ private_class_method :validate_out_name
+
+ def self.validate_in_name(in_out:, name:)
+ # in: columns may be duped
+ return if in_out == :in
+
+ raise CellValidationError, "output column name '#{name}' is also an input column"
+ end
+ private_class_method :validate_in_name
# def self.default_if(type)
# return nil if type == :set
# return :nil? if type == :'set/nil'
# :blank?
\ No newline at end of file