iostreams 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/docs/config.md +13 -9
  3. data/docs/copy_files.md +20 -2
  4. data/docs/extensions.md +18 -4
  5. data/docs/formats.md +644 -16
  6. data/docs/path.md +18 -2
  7. data/docs/streams.md +54 -9
  8. data/docs/tutorial.md +14 -2
  9. data/docs/upgrading.md +470 -23
  10. data/lib/io_streams/builder/deprecations.rb +250 -0
  11. data/lib/io_streams/builder.rb +256 -39
  12. data/lib/io_streams/bzip2/reader.rb +18 -2
  13. data/lib/io_streams/bzip2/writer.rb +11 -2
  14. data/lib/io_streams/deprecation/methods.rb +51 -0
  15. data/lib/io_streams/deprecation/once.rb +27 -0
  16. data/lib/io_streams/deprecation/option_names.rb +26 -0
  17. data/lib/io_streams/deprecation/words.rb +42 -0
  18. data/lib/io_streams/deprecation.rb +259 -0
  19. data/lib/io_streams/encode/reader.rb +54 -3
  20. data/lib/io_streams/encode/writer.rb +19 -2
  21. data/lib/io_streams/encode.rb +99 -0
  22. data/lib/io_streams/errors.rb +51 -0
  23. data/lib/io_streams/gzip/reader.rb +11 -0
  24. data/lib/io_streams/io_streams.rb +365 -35
  25. data/lib/io_streams/line/reader.rb +2 -1
  26. data/lib/io_streams/line/utf8_reader.rb +23 -0
  27. data/lib/io_streams/path.rb +125 -35
  28. data/lib/io_streams/paths/file.rb +72 -9
  29. data/lib/io_streams/paths/http.rb +48 -2
  30. data/lib/io_streams/paths/matcher.rb +6 -3
  31. data/lib/io_streams/paths/s3.rb +180 -9
  32. data/lib/io_streams/paths/sftp.rb +47 -3
  33. data/lib/io_streams/paths.rb +23 -0
  34. data/lib/io_streams/pgp/reader.rb +18 -0
  35. data/lib/io_streams/pgp/writer.rb +16 -0
  36. data/lib/io_streams/pgp.rb +16 -2
  37. data/lib/io_streams/reader.rb +44 -0
  38. data/lib/io_streams/record/reader.rb +59 -68
  39. data/lib/io_streams/record/writer.rb +17 -10
  40. data/lib/io_streams/row/header_row.rb +21 -0
  41. data/lib/io_streams/row/reader.rb +52 -15
  42. data/lib/io_streams/row/writer.rb +64 -13
  43. data/lib/io_streams/schema/columns.rb +456 -0
  44. data/lib/io_streams/schema/constraints.rb +99 -0
  45. data/lib/io_streams/schema/field.rb +967 -0
  46. data/lib/io_streams/schema/json_number.rb +56 -0
  47. data/lib/io_streams/schema/keys.rb +78 -0
  48. data/lib/io_streams/schema/pattern.rb +257 -0
  49. data/lib/io_streams/schema/source.rb +31 -0
  50. data/lib/io_streams/schema.rb +616 -0
  51. data/lib/io_streams/stream.rb +836 -67
  52. data/lib/io_streams/symmetric_encryption/reader.rb +8 -0
  53. data/lib/io_streams/tabular/header.rb +29 -0
  54. data/lib/io_streams/tabular/header_mapping.rb +332 -0
  55. data/lib/io_streams/tabular/mapping.rb +165 -0
  56. data/lib/io_streams/tabular/parser/array.rb +5 -0
  57. data/lib/io_streams/tabular/parser/base.rb +24 -0
  58. data/lib/io_streams/tabular/parser/fixed.rb +197 -0
  59. data/lib/io_streams/tabular/parser/fixed_fields.rb +160 -0
  60. data/lib/io_streams/tabular/parser/hash.rb +10 -0
  61. data/lib/io_streams/tabular/parser/json.rb +17 -0
  62. data/lib/io_streams/tabular/parser/json_fields.rb +132 -0
  63. data/lib/io_streams/tabular/schema_mapping.rb +361 -0
  64. data/lib/io_streams/tabular.rb +344 -30
  65. data/lib/io_streams/utils.rb +441 -6
  66. data/lib/io_streams/version.rb +1 -1
  67. data/lib/io_streams/writer.rb +27 -0
  68. data/lib/io_streams/xlsx/cells.rb +127 -0
  69. data/lib/io_streams/xlsx/reader.rb +56 -0
  70. data/lib/io_streams/xlsx/schema_reader.rb +90 -0
  71. data/lib/io_streams/xlsx/v3_writer.rb +16 -0
  72. data/lib/io_streams/zip/reader.rb +7 -0
  73. data/lib/io_streams/zip/writer.rb +24 -2
  74. data/lib/iostreams.rb +21 -17
  75. metadata +28 -2
@@ -7,6 +7,12 @@ module IOStreams
7
7
  []
8
8
  end
9
9
 
10
+ # Returns [Symbol] the tabular format of the text that a workbook is read as: CSV, one line for each row of its
11
+ # worksheet, see #file.
12
+ def self.text_format
13
+ :csv
14
+ end
15
+
10
16
  # Convert a xlsx, or xlsm file into CSV format.
11
17
  def self.file(file_name, &block)
12
18
  # Stream into a temp file as csv
@@ -16,6 +22,20 @@ module IOStreams
16
22
  end
17
23
  end
18
24
 
25
+ # Returns [Class] the class that reads a workbook for a file read with a schema, see
26
+ # `IOStreams::Builder#stream_class`, whose CSV text holds the text of each number cell as IOStreams 3.0 gives it,
27
+ # see `IOStreams::Xlsx::SchemaReader`, while this class keeps creek's text, as IOStreams 2.1 read it. A subclass,
28
+ # such as one that an application registers for `.xlsx`, reads a file with a schema itself.
29
+ def self.schema_reader
30
+ self == Reader ? SchemaReader : self
31
+ end
32
+
33
+ # Returns [Module] the stand-in for the writer of the files that this class reads, which IOStreams 3.0 adds, and
34
+ # IOStreams 2.2 does not have, which answers the options that it takes, see `IOStreams::Xlsx::V3Writer`.
35
+ def self.v3_writer
36
+ V3Writer
37
+ end
38
+
19
39
  def initialize(file_name)
20
40
  begin
21
41
  require "creek" unless defined?(Creek::Book)
@@ -31,6 +51,42 @@ module IOStreams
31
51
  def each
32
52
  @worksheet.rows.each { |row| yield row.values }
33
53
  end
54
+
55
+ private
56
+
57
+ # Converts each cell of the worksheet with the block, rather than with creek's `Creek::Sheet#convert`, when the
58
+ # block returns a value, which it calls with the text of the cell, its cell type, the index of its style, and
59
+ # `Creek::Sheet#converter_options`, which hold the first day of the workbook, and with creek's conversion when the
60
+ # block returns nil.
61
+ #
62
+ # Raises `IOStreams::Errors::Error` when the version of creek no longer has those methods, rather than let creek
63
+ # convert the cells itself.
64
+ def convert_cells(&block)
65
+ unless @worksheet.respond_to?(:convert, true) && @worksheet.respond_to?(:converter_options, true)
66
+ raise(IOStreams::Errors::Error, "creek #{Creek::VERSION} no longer has Creek::Sheet#convert and " \
67
+ "#converter_options, which IOStreams replaces to read the cells of a spreadsheet")
68
+ end
69
+
70
+ @worksheet.define_singleton_method(:convert) do |text, type, style_index|
71
+ value = block.call(text, type, style_index.to_i, converter_options)
72
+ value.nil? ? super(text, type, style_index) : value
73
+ end
74
+ end
75
+
76
+ # Returns [Array<Symbol|nil>] the class of the number format of each style of the workbook of the worksheet, as
77
+ # IOStreams 3.0 classifies it, see `IOStreams::Xlsx::Cells.number_formats`, rather than as creek does.
78
+ #
79
+ # Raises `IOStreams::Errors::Error` when the version of creek no longer has `Creek::Sheet#book` and
80
+ # `Creek::Styles#styles_xml`, which IOStreams reads the number formats of the workbook from.
81
+ def number_formats
82
+ unless @worksheet.respond_to?(:book) && defined?(Creek::Styles) && Creek::Styles.method_defined?(:styles_xml)
83
+ raise(IOStreams::Errors::Error, "creek #{Creek::VERSION} no longer has Creek::Sheet#book and " \
84
+ "Creek::Styles#styles_xml, which IOStreams reads the number formats of a " \
85
+ "spreadsheet from")
86
+ end
87
+
88
+ Cells.number_formats(Creek::Styles.new(@worksheet.book).styles_xml)
89
+ end
34
90
  end
35
91
  end
36
92
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IOStreams
4
+ module Xlsx
5
+ # Reads a workbook into CSV text as `IOStreams::Xlsx::Reader` does, for a file read with a schema, see
6
+ # `IOStreams::Xlsx::Reader.schema_reader`, with the text of each number cell as IOStreams 3.0 gives it, so that a
7
+ # `string` field reads the same text in both, and a field of the type of the cell reads it:
8
+ # a number the number that the cell holds, to the 15 significant digits that Excel displays, without
9
+ # its number format, such as `2134` for the zip code that creek reads as the Float `2134.0`,
10
+ # `0.3` for `0.30000000000000004`, `0.125` for `12.5%`, and `12.5` for a format without
11
+ # decimals, see .displayed
12
+ # a date in ISO 8601, such as `2026-10-25`
13
+ # a date and time the time of its clock in UTC, in ISO 8601, such as `2026-10-25T09:30:00Z`, since Excel has
14
+ # no time zone, rather than in the time zone of the process
15
+ # a time of day the time of its clock, such as `09:30:00`
16
+ #
17
+ # A number cell is one of the type `n`, or without a type, as Excel writes it, whose number format is a date or a
18
+ # time as IOStreams 3.0 classifies it, see `IOStreams::Xlsx::Cells`, such as the custom format `yyyy-mm-dd` of a
19
+ # date, rather than as creek does, which takes it as a date and time. Every other cell keeps creek's text, such as a
20
+ # text cell, keeping `01234`. A file read without a schema keeps creek's text for every cell, as IOStreams 2.1 read
21
+ # it.
22
+ class SchemaReader < Reader
23
+ # The most significant digits that Excel displays of a number.
24
+ DISPLAYED_DIGITS = 15
25
+
26
+ # The whole numbers that a Float holds exactly are below this, so that one keeps every digit, such as a card
27
+ # number of 16 digits, rather than the 15 that Excel displays, see .displayed.
28
+ EXACT = 2**53
29
+
30
+ # Returns [String|Object] the text of the number of a cell, a Float, as IOStreams 3.0 gives it: its 15 most
31
+ # significant digits, which Excel displays, rounded half up from its exact value, in plain digits, without a
32
+ # decimal point for a whole number, such as "2134" for `2134.0`, "0.3" for `0.30000000000000004`, or
33
+ # "150000000000000000000" for `1.5e20`, or every digit of a whole number below 2**53, which a Float holds exactly,
34
+ # such as "4111111111111111". Any other value is returned as it is.
35
+ def self.displayed(value)
36
+ return value unless value.is_a?(Float) && value.finite?
37
+ return value.to_i.to_s if value.abs < EXACT && value == value.truncate
38
+
39
+ # The exact value of the Float, rounded half up to the digits that Excel displays, counted from the first
40
+ # significant digit of its shortest text, as IOStreams 3.0 rounds it, with Rational, so that reading a
41
+ # spreadsheet does not need bigdecimal. Rounding the exact value, rather than its text, gives the same digits on
42
+ # every Ruby, since JRuby writes the text of some Floats with other digits than Ruby does.
43
+ digits = DISPLAYED_DIGITS - exponent(Rational(value.to_s))
44
+ decimal_text(value.to_r.round(digits, half: :up), digits)
45
+ end
46
+
47
+ # Returns [String|nil] the text of a cell of a number type, see the class comment, by the class of its number
48
+ # format, see `IOStreams::Xlsx::Cells.number_formats`, such as `:date`, with the first day of the workbook, or nil
49
+ # for text that is not a finite number, which creek converts. A number of a date or time format that is not a date
50
+ # that Excel holds, such as a negative number, which Excel shows as `####`, is a number.
51
+ def self.number_text(text, style, base_date)
52
+ number = Float(text, exception: false)
53
+ return unless number&.finite?
54
+
55
+ Cells.date_text(text, style, base_date) || displayed(number)
56
+ end
57
+
58
+ # Returns [Integer] the exponent of the number as a BigDecimal gives it, the place of its first significant digit,
59
+ # such as 4 for 2134, 0 for 0.3, and -6 for 0.0000001.
60
+ def self.exponent(number)
61
+ magnitude = number.abs
62
+ exponent = magnitude.numerator.to_s.length - magnitude.denominator.to_s.length
63
+ exponent += 1 while magnitude >= 10r**exponent
64
+ exponent -= 1 while magnitude < 10r**(exponent - 1)
65
+ exponent
66
+ end
67
+
68
+ # Returns [String] the text of the number rounded to the supplied digits after the decimal point, without a
69
+ # decimal point for a whole number, and without zeros at the end of its fraction, as `BigDecimal#to_s("F")` writes
70
+ # it, such as "0.0000001".
71
+ def self.decimal_text(number, digits)
72
+ return number.to_i.to_s if digits <= 0 || number.denominator == 1
73
+
74
+ scaled = (number * (10**digits)).to_i
75
+ text = scaled.abs.to_s.rjust(digits + 1, "0")
76
+ "#{'-' if scaled.negative?}#{text[0...-digits]}.#{text[-digits..].sub(/0+\z/, '')}"
77
+ end
78
+ private_class_method :exponent, :decimal_text
79
+
80
+ # Reads the first worksheet of the workbook, with the text of each number cell as .number_text gives it.
81
+ def initialize(file_name)
82
+ super
83
+ formats = number_formats
84
+ convert_cells do |text, type, style, options|
85
+ self.class.number_text(text, formats[style], options[:base_date]) if type.nil? || type == "n"
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,16 @@
1
+ module IOStreams
2
+ module Xlsx
3
+ # Stands for the writer of `.xlsx` and `.xlsm` files that IOStreams 3.0 adds, which IOStreams 2.2 does not have, see
4
+ # `IOStreams::Xlsx::Reader.v3_writer`, and answers the options that it takes, so that one of them set with `#option`,
5
+ # `#stream` or `#option_or_stream` is not reported as deprecated, while one that neither it nor the reader takes is,
6
+ # since IOStreams 3.0 raises ArgumentError for it when it is set, see `IOStreams::Builder#option`. It does not write:
7
+ # it is not registered, so writing a spreadsheet still raises ArgumentError.
8
+ module V3Writer
9
+ # Returns [Array<Symbol>] the options that the writer of IOStreams 3.0 takes, see
10
+ # `IOStreams::Deprecation::OptionNames#known_option_names`.
11
+ def self.known_option_names
12
+ %i[sheet_name auto_format use_shared_strings]
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,6 +5,13 @@ module IOStreams
5
5
  %i[entry_file_name]
6
6
  end
7
7
 
8
+ # Returns [Array<Symbol>] the methods that the stream that v3.0 supplies to a reader block, in place of the stream of
9
+ # the entry that this reader yields, such as a `Zip::InputStream`, answers: those of an IO that read, see
10
+ # `IOStreams::Reader.v3_stream_methods`.
11
+ def self.v3_stream_methods(_options)
12
+ V3_READ_METHODS
13
+ end
14
+
8
15
  # Read from a zip file or stream, decompressing the contents as it is read
9
16
  # The input stream from the first file found in the zip file is passed
10
17
  # to the supplied block.
@@ -5,9 +5,23 @@ module IOStreams
5
5
  %i[zip_file_name entry_file_name]
6
6
  end
7
7
 
8
+ # `zip_file_name` is deprecated, see `entry_file_name`, which replaces it, since IOStreams 3.0 raises
9
+ # ArgumentError for it. `#option`, `#stream` and `#option_or_stream` report a deprecation warning when it is set,
10
+ # even when it is nil, see `IOStreams::Builder#option`.
11
+ def self.replaced_option_names
12
+ {zip_file_name: :entry_file_name}
13
+ end
14
+
15
+ # The default of `zip_file_name`, which tells that it was not supplied.
16
+ NO_ZIP_FILE_NAME = Object.new.freeze
17
+ private_constant :NO_ZIP_FILE_NAME
18
+
8
19
  # When writing to a file, default the entry name within the zip to the file name
9
20
  # without the `.zip` extension, unless an entry name was explicitly supplied.
10
- def self.file(file_name, zip_file_name: nil, entry_file_name: zip_file_name, &)
21
+ #
22
+ # `zip_file_name` is deprecated, see .replaced_option_names.
23
+ def self.file(file_name, zip_file_name: NO_ZIP_FILE_NAME, entry_file_name: zip_file_name, &)
24
+ entry_file_name = supplied_entry_file_name(entry_file_name)
11
25
  entry_file_name = file_name.to_s[0..-5] if entry_file_name.nil? && file_name.to_s =~ /\.zip\z/i
12
26
 
13
27
  super(file_name, entry_file_name: entry_file_name, &)
@@ -34,7 +48,8 @@ module IOStreams
34
48
  # then copied across. `zip_kit` streams to non-seekable outputs by emitting
35
49
  # data descriptors instead, so we can write straight to the output stream and
36
50
  # avoid the temp file round-trip.
37
- def self.stream(output_stream, zip_file_name: nil, entry_file_name: zip_file_name)
51
+ def self.stream(output_stream, zip_file_name: NO_ZIP_FILE_NAME, entry_file_name: zip_file_name)
52
+ entry_file_name = supplied_entry_file_name(entry_file_name)
38
53
  entry_file_name ||= "file"
39
54
 
40
55
  Utils.load_soft_dependency("zip_kit", "Zip") unless defined?(ZipKit::Streamer)
@@ -45,6 +60,13 @@ module IOStreams
45
60
  end
46
61
  result
47
62
  end
63
+
64
+ # Returns [String|nil] the entry name supplied, whose default is `zip_file_name`, or nil when neither was
65
+ # supplied.
66
+ def self.supplied_entry_file_name(entry_file_name)
67
+ entry_file_name unless entry_file_name.equal?(NO_ZIP_FILE_NAME)
68
+ end
69
+ private_class_method :supplied_entry_file_name
48
70
  end
49
71
  end
50
72
  end
data/lib/iostreams.rb CHANGED
@@ -1,15 +1,18 @@
1
1
  require "io_streams/version"
2
2
  # @formatter:off
3
3
  module IOStreams
4
- autoload :Builder, "io_streams/builder"
5
- autoload :Errors, "io_streams/errors"
6
- autoload :Path, "io_streams/path"
7
- autoload :Pgp, "io_streams/pgp"
8
- autoload :Reader, "io_streams/reader"
9
- autoload :Stream, "io_streams/stream"
10
- autoload :Tabular, "io_streams/tabular"
11
- autoload :Utils, "io_streams/utils"
12
- autoload :Writer, "io_streams/writer"
4
+ autoload :Builder, "io_streams/builder"
5
+ autoload :Deprecation, "io_streams/deprecation"
6
+ autoload :Encode, "io_streams/encode"
7
+ autoload :Errors, "io_streams/errors"
8
+ autoload :Path, "io_streams/path"
9
+ autoload :Pgp, "io_streams/pgp"
10
+ autoload :Reader, "io_streams/reader"
11
+ autoload :Schema, "io_streams/schema"
12
+ autoload :Stream, "io_streams/stream"
13
+ autoload :Tabular, "io_streams/tabular"
14
+ autoload :Utils, "io_streams/utils"
15
+ autoload :Writer, "io_streams/writer"
13
16
 
14
17
  module Paths
15
18
  autoload :File, "io_streams/paths/file"
@@ -24,19 +27,15 @@ module IOStreams
24
27
  autoload :Writer, "io_streams/bzip2/writer"
25
28
  end
26
29
 
27
- module Encode
28
- autoload :Reader, "io_streams/encode/reader"
29
- autoload :Writer, "io_streams/encode/writer"
30
- end
31
-
32
30
  module Gzip
33
31
  autoload :Reader, "io_streams/gzip/reader"
34
32
  autoload :Writer, "io_streams/gzip/writer"
35
33
  end
36
34
 
37
35
  module Line
38
- autoload :Reader, "io_streams/line/reader"
39
- autoload :Writer, "io_streams/line/writer"
36
+ autoload :Reader, "io_streams/line/reader"
37
+ autoload :Utf8Reader, "io_streams/line/utf8_reader"
38
+ autoload :Writer, "io_streams/line/writer"
40
39
  end
41
40
 
42
41
  module Record
@@ -45,6 +44,7 @@ module IOStreams
45
44
  end
46
45
 
47
46
  module Row
47
+ autoload :HeaderRow, "io_streams/row/header_row"
48
48
  autoload :Reader, "io_streams/row/reader"
49
49
  autoload :Writer, "io_streams/row/writer"
50
50
  end
@@ -55,7 +55,10 @@ module IOStreams
55
55
  end
56
56
 
57
57
  module Xlsx
58
- autoload :Reader, "io_streams/xlsx/reader"
58
+ autoload :Cells, "io_streams/xlsx/cells"
59
+ autoload :Reader, "io_streams/xlsx/reader"
60
+ autoload :SchemaReader, "io_streams/xlsx/schema_reader"
61
+ autoload :V3Writer, "io_streams/xlsx/v3_writer"
59
62
  end
60
63
 
61
64
  module Zip
@@ -63,4 +66,5 @@ module IOStreams
63
66
  autoload :Writer, "io_streams/zip/writer"
64
67
  end
65
68
  end
69
+ require "io_streams/paths"
66
70
  require "io_streams/io_streams"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iostreams
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
@@ -46,8 +46,15 @@ files:
46
46
  - docs/tutorial.md
47
47
  - docs/upgrading.md
48
48
  - lib/io_streams/builder.rb
49
+ - lib/io_streams/builder/deprecations.rb
49
50
  - lib/io_streams/bzip2/reader.rb
50
51
  - lib/io_streams/bzip2/writer.rb
52
+ - lib/io_streams/deprecation.rb
53
+ - lib/io_streams/deprecation/methods.rb
54
+ - lib/io_streams/deprecation/once.rb
55
+ - lib/io_streams/deprecation/option_names.rb
56
+ - lib/io_streams/deprecation/words.rb
57
+ - lib/io_streams/encode.rb
51
58
  - lib/io_streams/encode/reader.rb
52
59
  - lib/io_streams/encode/writer.rb
53
60
  - lib/io_streams/errors.rb
@@ -55,8 +62,10 @@ files:
55
62
  - lib/io_streams/gzip/writer.rb
56
63
  - lib/io_streams/io_streams.rb
57
64
  - lib/io_streams/line/reader.rb
65
+ - lib/io_streams/line/utf8_reader.rb
58
66
  - lib/io_streams/line/writer.rb
59
67
  - lib/io_streams/path.rb
68
+ - lib/io_streams/paths.rb
60
69
  - lib/io_streams/paths/file.rb
61
70
  - lib/io_streams/paths/http.rb
62
71
  - lib/io_streams/paths/matcher.rb
@@ -69,24 +78,41 @@ files:
69
78
  - lib/io_streams/reader.rb
70
79
  - lib/io_streams/record/reader.rb
71
80
  - lib/io_streams/record/writer.rb
81
+ - lib/io_streams/row/header_row.rb
72
82
  - lib/io_streams/row/reader.rb
73
83
  - lib/io_streams/row/writer.rb
84
+ - lib/io_streams/schema.rb
85
+ - lib/io_streams/schema/columns.rb
86
+ - lib/io_streams/schema/constraints.rb
87
+ - lib/io_streams/schema/field.rb
88
+ - lib/io_streams/schema/json_number.rb
89
+ - lib/io_streams/schema/keys.rb
90
+ - lib/io_streams/schema/pattern.rb
91
+ - lib/io_streams/schema/source.rb
74
92
  - lib/io_streams/stream.rb
75
93
  - lib/io_streams/symmetric_encryption/reader.rb
76
94
  - lib/io_streams/symmetric_encryption/writer.rb
77
95
  - lib/io_streams/tabular.rb
78
96
  - lib/io_streams/tabular/header.rb
97
+ - lib/io_streams/tabular/header_mapping.rb
98
+ - lib/io_streams/tabular/mapping.rb
79
99
  - lib/io_streams/tabular/parser/array.rb
80
100
  - lib/io_streams/tabular/parser/base.rb
81
101
  - lib/io_streams/tabular/parser/csv.rb
82
102
  - lib/io_streams/tabular/parser/fixed.rb
103
+ - lib/io_streams/tabular/parser/fixed_fields.rb
83
104
  - lib/io_streams/tabular/parser/hash.rb
84
105
  - lib/io_streams/tabular/parser/json.rb
106
+ - lib/io_streams/tabular/parser/json_fields.rb
85
107
  - lib/io_streams/tabular/parser/psv.rb
108
+ - lib/io_streams/tabular/schema_mapping.rb
86
109
  - lib/io_streams/utils.rb
87
110
  - lib/io_streams/version.rb
88
111
  - lib/io_streams/writer.rb
112
+ - lib/io_streams/xlsx/cells.rb
89
113
  - lib/io_streams/xlsx/reader.rb
114
+ - lib/io_streams/xlsx/schema_reader.rb
115
+ - lib/io_streams/xlsx/v3_writer.rb
90
116
  - lib/io_streams/zip/reader.rb
91
117
  - lib/io_streams/zip/writer.rb
92
118
  - lib/iostreams.rb
@@ -98,7 +124,7 @@ metadata:
98
124
  changelog_uri: https://github.com/reidmorrison/iostreams/blob/main/CHANGELOG.md
99
125
  documentation_uri: https://iostreams.reidmorrison.com
100
126
  homepage_uri: https://iostreams.reidmorrison.com
101
- source_code_uri: https://github.com/reidmorrison/iostreams/tree/v2.1.0
127
+ source_code_uri: https://github.com/reidmorrison/iostreams/tree/v2.2.0
102
128
  rubygems_mfa_required: 'true'
103
129
  rdoc_options: []
104
130
  require_paths: