summaryrefslogtreecommitdiff
path: root/lib/csv/fields_converter.rb
diff options
context:
space:
mode:
authorkou <kou@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-23 07:00:35 +0000
committerkou <kou@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-23 07:00:35 +0000
commite5d634260e7927db284fd7d2d656899443f5c53e (patch)
tree31f579715ae8c73ee8094c258b634f1186a0946a /lib/csv/fields_converter.rb
parentc20a1946a6d7b260f1f0f3038b7af081174d6cd9 (diff)
Import CSV 3.0.2
This includes performance improvement especially writing. Writing is about 2 times faster. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66507 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/csv/fields_converter.rb')
-rw-r--r--lib/csv/fields_converter.rb78
1 files changed, 78 insertions, 0 deletions
diff --git a/lib/csv/fields_converter.rb b/lib/csv/fields_converter.rb
new file mode 100644
index 0000000000..c2fa5798ff
--- /dev/null
+++ b/lib/csv/fields_converter.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+class CSV
+ class FieldsConverter
+ include Enumerable
+
+ def initialize(options={})
+ @converters = []
+ @nil_value = options[:nil_value]
+ @empty_value = options[:empty_value]
+ @empty_value_is_empty_string = (@empty_value == "")
+ @accept_nil = options[:accept_nil]
+ @builtin_converters = options[:builtin_converters]
+ @need_static_convert = need_static_convert?
+ end
+
+ def add_converter(name=nil, &converter)
+ if name.nil? # custom converter
+ @converters << converter
+ else # named converter
+ combo = @builtin_converters[name]
+ case combo
+ when Array # combo converter
+ combo.each do |sub_name|
+ add_converter(sub_name)
+ end
+ else # individual named converter
+ @converters << combo
+ end
+ end
+ end
+
+ def each(&block)
+ @converters.each(&block)
+ end
+
+ def empty?
+ @converters.empty?
+ end
+
+ def convert(fields, headers, lineno)
+ return fields unless need_convert?
+
+ fields.collect.with_index do |field, index|
+ if field.nil?
+ field = @nil_value
+ elsif field.empty?
+ field = @empty_value unless @empty_value_is_empty_string
+ end
+ @converters.each do |converter|
+ break if field.nil? and @accept_nil
+ if converter.arity == 1 # straight field converter
+ field = converter[field]
+ else # FieldInfo converter
+ if headers
+ header = headers[index]
+ else
+ header = nil
+ end
+ field = converter[field, FieldInfo.new(index, lineno, header)]
+ end
+ break unless field.is_a?(String) # short-circuit pipeline for speed
+ end
+ field # final state of each field, converted or original
+ end
+ end
+
+ private
+ def need_static_convert?
+ not (@nil_value.nil? and @empty_value_is_empty_string)
+ end
+
+ def need_convert?
+ @need_static_convert or
+ (not @converters.empty?)
+ end
+ end
+end