honey_format 0.16.0 → 0.17.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.
- checksums.yaml +4 -4
- data/.hound.yml +3 -0
- data/.rubocop.yml +7 -0
- data/.ruby-style-guide.yml +264 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -0
- data/README.md +63 -15
- data/Rakefile +2 -0
- data/bin/benchmark +2 -0
- data/bin/console +1 -0
- data/exe/honey_format +1 -0
- data/honey_format.gemspec +5 -4
- data/lib/honey_format/cli/benchmark_cli.rb +15 -13
- data/lib/honey_format/cli/cli.rb +17 -12
- data/lib/honey_format/cli/result_writer.rb +2 -0
- data/lib/honey_format/configuration.rb +114 -11
- data/lib/honey_format/converters/convert_boolean.rb +24 -0
- data/lib/honey_format/converters/convert_date_and_time.rb +30 -0
- data/lib/honey_format/converters/convert_number.rb +33 -0
- data/lib/honey_format/converters/convert_string.rb +42 -0
- data/lib/honey_format/converters/converters.rb +12 -0
- data/lib/honey_format/converters/header_column_converter.rb +57 -0
- data/lib/honey_format/csv.rb +22 -14
- data/lib/honey_format/errors.rb +8 -2
- data/lib/honey_format/helpers/helpers.rb +41 -0
- data/lib/honey_format/{header.rb → matrix/header.rb} +48 -12
- data/lib/honey_format/matrix/matrix.rb +104 -0
- data/lib/honey_format/{row.rb → matrix/row.rb} +6 -3
- data/lib/honey_format/{row_builder.rb → matrix/row_builder.rb} +5 -4
- data/lib/honey_format/{rows.rb → matrix/rows.rb} +7 -4
- data/lib/honey_format/matrix.rb +6 -89
- data/lib/honey_format/registry.rb +99 -0
- data/lib/honey_format/version.rb +4 -2
- data/lib/honey_format.rb +14 -6
- metadata +34 -24
- data/lib/honey_format/header_column_converter.rb +0 -40
- data/lib/honey_format/value_converter.rb +0 -117
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 997883e33f720a7dc6c0d3f2a552b4dcd68cfa1bac8be23d5a36332c83bf0e32
         | 
| 4 | 
            +
              data.tar.gz: dd522a2171b7befc1e41e80022dade22d18d3d9228c8b40eb6b7d3f8d032005b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c6e15af7156b78f97f02e1e42f9c961116ad7e09428ccaa6eb7b0651d93f162f2417381d034b82eaefa843d0b5aceab1cfb824347db1701ed5186d575c6d88eb
         | 
| 7 | 
            +
              data.tar.gz: dfa13256a8446d9b7f6bedf4505e9c275268999098befd62a81174ef5d682185ea4e379e07b870e3554ecdb983714bac31b1175422dd750dc07d6997b52233b9
         | 
    
        data/.hound.yml
    ADDED
    
    
    
        data/.rubocop.yml
    ADDED
    
    
| @@ -0,0 +1,264 @@ | |
| 1 | 
            +
            Rails:
         | 
| 2 | 
            +
              Enabled: false
         | 
| 3 | 
            +
            AllCops:
         | 
| 4 | 
            +
              TargetRubyVersion: 2.3
         | 
| 5 | 
            +
              Exclude:
         | 
| 6 | 
            +
                - "vendor/**/*"
         | 
| 7 | 
            +
              UseCache: true
         | 
| 8 | 
            +
            Style/CollectionMethods:
         | 
| 9 | 
            +
              Description: Preferred collection methods.
         | 
| 10 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
         | 
| 11 | 
            +
              Enabled: true
         | 
| 12 | 
            +
              PreferredMethods:
         | 
| 13 | 
            +
                collect: map
         | 
| 14 | 
            +
                collect!: map!
         | 
| 15 | 
            +
                find: detect
         | 
| 16 | 
            +
                find_all: select
         | 
| 17 | 
            +
                reduce: inject
         | 
| 18 | 
            +
            Style/RedundantFreeze:
         | 
| 19 | 
            +
              Description: "Checks usages of Object#freeze on immutable objects."
         | 
| 20 | 
            +
              Enabled: false
         | 
| 21 | 
            +
            Layout/DotPosition:
         | 
| 22 | 
            +
              Description: Checks the position of the dot in multi-line method calls.
         | 
| 23 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
         | 
| 24 | 
            +
              Enabled: true
         | 
| 25 | 
            +
              EnforcedStyle: trailing
         | 
| 26 | 
            +
              SupportedStyles:
         | 
| 27 | 
            +
              - leading
         | 
| 28 | 
            +
              - trailing
         | 
| 29 | 
            +
            Naming/FileName:
         | 
| 30 | 
            +
              Description: Use snake_case for source file names.
         | 
| 31 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
         | 
| 32 | 
            +
              Enabled: false
         | 
| 33 | 
            +
              Exclude: []
         | 
| 34 | 
            +
            Naming/MemoizedInstanceVariableName:
         | 
| 35 | 
            +
              Description: Memoized method name should match memo instance variable name.
         | 
| 36 | 
            +
              Enabled: false
         | 
| 37 | 
            +
            Naming/UncommunicativeMethodParamName:
         | 
| 38 | 
            +
              Description: >-
         | 
| 39 | 
            +
                            Checks for method parameter names that contain capital letters,
         | 
| 40 | 
            +
                            end in numbers, or do not meet a minimal length.
         | 
| 41 | 
            +
              Enabled: false
         | 
| 42 | 
            +
            Style/GuardClause:
         | 
| 43 | 
            +
              Description: Check for conditionals that can be replaced with guard clauses
         | 
| 44 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
         | 
| 45 | 
            +
              Enabled: true
         | 
| 46 | 
            +
              MinBodyLength: 3
         | 
| 47 | 
            +
            Style/IfUnlessModifier:
         | 
| 48 | 
            +
              Description: Favor modifier if/unless usage when you have a single-line body.
         | 
| 49 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
         | 
| 50 | 
            +
              Enabled: false
         | 
| 51 | 
            +
            Style/OptionHash:
         | 
| 52 | 
            +
              Description: Don't use option hashes when you can use keyword arguments.
         | 
| 53 | 
            +
              Enabled: false
         | 
| 54 | 
            +
            Style/PercentLiteralDelimiters:
         | 
| 55 | 
            +
              Description: Use `%`-literal delimiters consistently
         | 
| 56 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
         | 
| 57 | 
            +
              Enabled: false
         | 
| 58 | 
            +
              PreferredDelimiters:
         | 
| 59 | 
            +
                "%": "()"
         | 
| 60 | 
            +
                "%i": "()"
         | 
| 61 | 
            +
                "%q": "()"
         | 
| 62 | 
            +
                "%Q": "()"
         | 
| 63 | 
            +
                "%r": "{}"
         | 
| 64 | 
            +
                "%s": "()"
         | 
| 65 | 
            +
                "%w": "()"
         | 
| 66 | 
            +
                "%W": "()"
         | 
| 67 | 
            +
                "%x": "()"
         | 
| 68 | 
            +
            Naming/PredicateName:
         | 
| 69 | 
            +
              Description: Check the names of predicate methods.
         | 
| 70 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
         | 
| 71 | 
            +
              Enabled: true
         | 
| 72 | 
            +
              NamePrefix:
         | 
| 73 | 
            +
              - is_
         | 
| 74 | 
            +
              - has_
         | 
| 75 | 
            +
              - have_
         | 
| 76 | 
            +
              NamePrefixBlacklist:
         | 
| 77 | 
            +
              - is_
         | 
| 78 | 
            +
              Exclude:
         | 
| 79 | 
            +
              - spec/**/*
         | 
| 80 | 
            +
            Style/RaiseArgs:
         | 
| 81 | 
            +
              Description: Checks the arguments passed to raise/fail.
         | 
| 82 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
         | 
| 83 | 
            +
              Enabled: false
         | 
| 84 | 
            +
              EnforcedStyle: exploded
         | 
| 85 | 
            +
              SupportedStyles:
         | 
| 86 | 
            +
              - compact
         | 
| 87 | 
            +
              - exploded
         | 
| 88 | 
            +
            Style/SignalException:
         | 
| 89 | 
            +
              Description: Checks for proper usage of fail and raise.
         | 
| 90 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
         | 
| 91 | 
            +
              Enabled: false
         | 
| 92 | 
            +
              EnforcedStyle: semantic
         | 
| 93 | 
            +
              SupportedStyles:
         | 
| 94 | 
            +
              - only_raise
         | 
| 95 | 
            +
              - only_fail
         | 
| 96 | 
            +
              - semantic
         | 
| 97 | 
            +
            Style/SingleLineBlockParams:
         | 
| 98 | 
            +
              Description: Enforces the names of some block params.
         | 
| 99 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
         | 
| 100 | 
            +
              Enabled: false
         | 
| 101 | 
            +
              Methods:
         | 
| 102 | 
            +
              - reduce:
         | 
| 103 | 
            +
                - a
         | 
| 104 | 
            +
                - e
         | 
| 105 | 
            +
              - inject:
         | 
| 106 | 
            +
                - a
         | 
| 107 | 
            +
                - e
         | 
| 108 | 
            +
            Style/TrivialAccessors:
         | 
| 109 | 
            +
              Enabled: false
         | 
| 110 | 
            +
            Style/SingleLineMethods:
         | 
| 111 | 
            +
              Description: Avoid single-line methods.
         | 
| 112 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
         | 
| 113 | 
            +
              Enabled: false
         | 
| 114 | 
            +
              AllowIfMethodIsEmpty: true
         | 
| 115 | 
            +
            Style/StringLiterals:
         | 
| 116 | 
            +
              Description: Checks if uses of quotes match the configured preference.
         | 
| 117 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
         | 
| 118 | 
            +
              Enabled: true
         | 
| 119 | 
            +
              EnforcedStyle: single_quotes
         | 
| 120 | 
            +
              SupportedStyles:
         | 
| 121 | 
            +
              - single_quotes
         | 
| 122 | 
            +
              - double_quotes
         | 
| 123 | 
            +
            Style/MixinUsage:
         | 
| 124 | 
            +
              Enabled: true
         | 
| 125 | 
            +
              Exclude:
         | 
| 126 | 
            +
                - exe/*
         | 
| 127 | 
            +
            Style/StringLiteralsInInterpolation:
         | 
| 128 | 
            +
              Description: Checks if uses of quotes inside expressions in interpolated strings
         | 
| 129 | 
            +
                match the configured preference.
         | 
| 130 | 
            +
              Enabled: true
         | 
| 131 | 
            +
              EnforcedStyle: single_quotes
         | 
| 132 | 
            +
              SupportedStyles:
         | 
| 133 | 
            +
              - single_quotes
         | 
| 134 | 
            +
              - double_quotes
         | 
| 135 | 
            +
            Style/TrailingCommaInArrayLiteral:
         | 
| 136 | 
            +
              Description: Checks for trailing comma in parameter lists and literals.
         | 
| 137 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
         | 
| 138 | 
            +
              Enabled: true
         | 
| 139 | 
            +
              EnforcedStyleForMultiline: comma
         | 
| 140 | 
            +
            Style/TrailingCommaInHashLiteral:
         | 
| 141 | 
            +
              Description: Checks for trailing comma in parameter lists and literals.
         | 
| 142 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
         | 
| 143 | 
            +
              Enabled: true
         | 
| 144 | 
            +
              EnforcedStyleForMultiline: comma
         | 
| 145 | 
            +
            Metrics/AbcSize:
         | 
| 146 | 
            +
              Description: A calculated magnitude based on number of assignments, branches, and
         | 
| 147 | 
            +
                conditions.
         | 
| 148 | 
            +
              Enabled: false
         | 
| 149 | 
            +
              Max: 15
         | 
| 150 | 
            +
            Metrics/ClassLength:
         | 
| 151 | 
            +
              Description: Avoid classes longer than 100 lines of code.
         | 
| 152 | 
            +
              Enabled: false
         | 
| 153 | 
            +
              CountComments: false
         | 
| 154 | 
            +
              Max: 100
         | 
| 155 | 
            +
            Metrics/ModuleLength:
         | 
| 156 | 
            +
              CountComments: false
         | 
| 157 | 
            +
              Max: 100
         | 
| 158 | 
            +
              Description: Avoid modules longer than 100 lines of code.
         | 
| 159 | 
            +
              Enabled: false
         | 
| 160 | 
            +
            Metrics/CyclomaticComplexity:
         | 
| 161 | 
            +
              Description: A complexity metric that is strongly correlated to the number of test
         | 
| 162 | 
            +
                cases needed to validate a method.
         | 
| 163 | 
            +
              Enabled: false
         | 
| 164 | 
            +
              Max: 6
         | 
| 165 | 
            +
            Metrics/MethodLength:
         | 
| 166 | 
            +
              Description: Avoid methods longer than 10 lines of code.
         | 
| 167 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
         | 
| 168 | 
            +
              Enabled: false
         | 
| 169 | 
            +
              CountComments: false
         | 
| 170 | 
            +
              Max: 10
         | 
| 171 | 
            +
            Metrics/ParameterLists:
         | 
| 172 | 
            +
              Description: Avoid parameter lists longer than three or four parameters.
         | 
| 173 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
         | 
| 174 | 
            +
              Enabled: false
         | 
| 175 | 
            +
              Max: 5
         | 
| 176 | 
            +
              CountKeywordArgs: true
         | 
| 177 | 
            +
            Metrics/PerceivedComplexity:
         | 
| 178 | 
            +
              Description: A complexity metric geared towards measuring complexity for a human
         | 
| 179 | 
            +
                reader.
         | 
| 180 | 
            +
              Enabled: false
         | 
| 181 | 
            +
              Max: 7
         | 
| 182 | 
            +
            Metrics/LineLength:
         | 
| 183 | 
            +
              Description: Maximum line length
         | 
| 184 | 
            +
              Enabled: true
         | 
| 185 | 
            +
              Max: 95
         | 
| 186 | 
            +
              Exclude:
         | 
| 187 | 
            +
              - lib/honey_format/cli/*
         | 
| 188 | 
            +
              - Gemfile
         | 
| 189 | 
            +
              - honey_format.gemspec
         | 
| 190 | 
            +
              - spec/**/*
         | 
| 191 | 
            +
            Metrics/BlockLength:
         | 
| 192 | 
            +
              Enabled: true
         | 
| 193 | 
            +
              Exclude:
         | 
| 194 | 
            +
              - lib/honey_format/cli/*
         | 
| 195 | 
            +
              - spec/**/*
         | 
| 196 | 
            +
            Lint/AssignmentInCondition:
         | 
| 197 | 
            +
              Description: Don't use assignment in conditions.
         | 
| 198 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
         | 
| 199 | 
            +
              Enabled: false
         | 
| 200 | 
            +
              AllowSafeAssignment: true
         | 
| 201 | 
            +
            Style/InlineComment:
         | 
| 202 | 
            +
              Description: Avoid inline comments.
         | 
| 203 | 
            +
              Enabled: false
         | 
| 204 | 
            +
            Naming/AccessorMethodName:
         | 
| 205 | 
            +
              Description: Check the naming of accessor methods for get_/set_.
         | 
| 206 | 
            +
              Enabled: false
         | 
| 207 | 
            +
            Style/Alias:
         | 
| 208 | 
            +
              Description: Use alias_method instead of alias.
         | 
| 209 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
         | 
| 210 | 
            +
              Enabled: false
         | 
| 211 | 
            +
            Style/Documentation:
         | 
| 212 | 
            +
              Description: Document classes and non-namespace modules.
         | 
| 213 | 
            +
              Enabled: false
         | 
| 214 | 
            +
            Style/DoubleNegation:
         | 
| 215 | 
            +
              Description: Checks for uses of double negation (!!).
         | 
| 216 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
         | 
| 217 | 
            +
              Enabled: false
         | 
| 218 | 
            +
            Style/EachWithObject:
         | 
| 219 | 
            +
              Description: Prefer `each_with_object` over `inject` or `reduce`.
         | 
| 220 | 
            +
              Enabled: false
         | 
| 221 | 
            +
            Style/EmptyLiteral:
         | 
| 222 | 
            +
              Description: Prefer literals to Array.new/Hash.new/String.new.
         | 
| 223 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
         | 
| 224 | 
            +
              Enabled: false
         | 
| 225 | 
            +
            Style/ModuleFunction:
         | 
| 226 | 
            +
              Description: Checks for usage of `extend self` in modules.
         | 
| 227 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
         | 
| 228 | 
            +
              Enabled: false
         | 
| 229 | 
            +
            Style/OneLineConditional:
         | 
| 230 | 
            +
              Description: Favor the ternary operator(?:) over if/then/else/end constructs.
         | 
| 231 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
         | 
| 232 | 
            +
              Enabled: false
         | 
| 233 | 
            +
            Style/PerlBackrefs:
         | 
| 234 | 
            +
              Description: Avoid Perl-style regex back references.
         | 
| 235 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
         | 
| 236 | 
            +
              Enabled: false
         | 
| 237 | 
            +
            Style/Send:
         | 
| 238 | 
            +
              Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
         | 
| 239 | 
            +
                may overlap with existing methods.
         | 
| 240 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
         | 
| 241 | 
            +
              Enabled: false
         | 
| 242 | 
            +
            Style/SpecialGlobalVars:
         | 
| 243 | 
            +
              Description: Avoid Perl-style global variables.
         | 
| 244 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
         | 
| 245 | 
            +
              Enabled: false
         | 
| 246 | 
            +
            Style/VariableInterpolation:
         | 
| 247 | 
            +
              Description: Don't interpolate global, instance and class variables directly in
         | 
| 248 | 
            +
                strings.
         | 
| 249 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
         | 
| 250 | 
            +
              Enabled: false
         | 
| 251 | 
            +
            Style/WhenThen:
         | 
| 252 | 
            +
              Description: Use when x then ... for one-line cases.
         | 
| 253 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
         | 
| 254 | 
            +
              Enabled: false
         | 
| 255 | 
            +
            Lint/EachWithObjectArgument:
         | 
| 256 | 
            +
              Description: Check for immutable argument given to each_with_object.
         | 
| 257 | 
            +
              Enabled: true
         | 
| 258 | 
            +
            Lint/HandleExceptions:
         | 
| 259 | 
            +
              Description: Don't suppress exception.
         | 
| 260 | 
            +
              StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
         | 
| 261 | 
            +
              Enabled: false
         | 
| 262 | 
            +
            Lint/LiteralInInterpolation:
         | 
| 263 | 
            +
              Description: Checks for literals used in interpolation.
         | 
| 264 | 
            +
              Enabled: false
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,20 @@ | |
| 1 1 | 
             
            # HEAD
         | 
| 2 2 |  | 
| 3 | 
            +
            ## v0.17.0
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            :warning: This release contains some backwards compatible changes.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Add global config for CSV `delimiter`, `row_delimiter`, `quote_character` and `skip_lines`
         | 
| 8 | 
            +
            * Add `header_deduplicator` support to Matrix & CSV
         | 
| 9 | 
            +
            * Make `HeaderColumnConverter` normalization even more aggressive [PR#32](https://github.com/buren/honey_format/pull/32)
         | 
| 10 | 
            +
              - :warning: Backwards incompatible
         | 
| 11 | 
            +
            * Add `blank` type [PR#34](https://github.com/buren/honey_format/pull/34)
         | 
| 12 | 
            +
            * Rename `ValueConverter` => `Registry` and generalize implementation
         | 
| 13 | 
            +
            * Rename `UnknownValueTypeError` => `UnknownTypeError`
         | 
| 14 | 
            +
              - :warning: Backwards incompatible
         | 
| 15 | 
            +
            * Allow unregister of existing value converters
         | 
| 16 | 
            +
            * Add `hex` and `blank` converters to registry
         | 
| 17 | 
            +
             | 
| 3 18 | 
             
            ## v0.16.0
         | 
| 4 19 |  | 
| 5 20 | 
             
            * Add `--type-map` option to CLI
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -7,10 +7,10 @@ Proper objects for CSV headers and rows, convert column values, filter columns a | |
| 7 7 | 
             
            ## Features
         | 
| 8 8 |  | 
| 9 9 | 
             
            - Proper objects for CSV header and rows
         | 
| 10 | 
            -
            - Convert column values
         | 
| 10 | 
            +
            - Convert row and header column values
         | 
| 11 11 | 
             
            - Pass your own custom row builder
         | 
| 12 | 
            -
            - Convert header column names
         | 
| 13 12 | 
             
            - Filter what columns and rows are included in CSV output
         | 
| 13 | 
            +
            - Gracefully handle missing and duplicated header columns
         | 
| 14 14 | 
             
            - [CLI](#cli) - Simple command line interface
         | 
| 15 15 | 
             
            - Only ~5-10% overhead from using Ruby CSV, see [benchmarks](#benchmark)
         | 
| 16 16 | 
             
            - Has no dependencies other than Ruby stdlib
         | 
| @@ -20,7 +20,6 @@ Read the [usage section](#usage),  [RubyDoc](https://www.rubydoc.info/gems/honey | |
| 20 20 |  | 
| 21 21 | 
             
            ## Quick use
         | 
| 22 22 |  | 
| 23 | 
            -
             | 
| 24 23 | 
             
            ```ruby
         | 
| 25 24 | 
             
            csv_string = <<-CSV
         | 
| 26 25 | 
             
            Id,Username,Email
         | 
| @@ -29,7 +28,7 @@ Id,Username,Email | |
| 29 28 | 
             
            CSV
         | 
| 30 29 | 
             
            csv = HoneyFormat::CSV.new(csv_string, type_map: { id: :integer })
         | 
| 31 30 | 
             
            csv.columns     # => [:id, :username]
         | 
| 32 | 
            -
            user = csv.rows # => [#<Row id= | 
| 31 | 
            +
            user = csv.rows # => [#<Row id=1, username="buren">]
         | 
| 33 32 | 
             
            user.id         # => 1
         | 
| 34 33 | 
             
            user.username   # => "buren"
         | 
| 35 34 |  | 
| @@ -66,7 +65,7 @@ csv = HoneyFormat::CSV.new(csv_string) | |
| 66 65 | 
             
            # Header
         | 
| 67 66 | 
             
            header = csv.header
         | 
| 68 67 | 
             
            header.original # => ["Id", "Username"]
         | 
| 69 | 
            -
            header.columns | 
| 68 | 
            +
            header.columns  # => [:id, :username]
         | 
| 70 69 |  | 
| 71 70 |  | 
| 72 71 | 
             
            # Rows
         | 
| @@ -102,7 +101,7 @@ csv.rows.first.id # => 1 | |
| 102 101 | 
             
            Add your own converter
         | 
| 103 102 | 
             
            ```ruby
         | 
| 104 103 | 
             
            HoneyFormat.configure do |config|
         | 
| 105 | 
            -
              config. | 
| 104 | 
            +
              config.converter_registry.register :upcased, proc { |v| v.upcase }
         | 
| 106 105 | 
             
            end
         | 
| 107 106 |  | 
| 108 107 | 
             
            csv_string = "Id,Username\n1,buren"
         | 
| @@ -111,13 +110,22 @@ csv = HoneyFormat::CSV.new(csv_string, type_map: type_map) | |
| 111 110 | 
             
            csv.rows.first.username # => "BUREN"
         | 
| 112 111 | 
             
            ```
         | 
| 113 112 |  | 
| 113 | 
            +
            Remove registered converter
         | 
| 114 | 
            +
            ```ruby
         | 
| 115 | 
            +
            HoneyFormat.configure do |config|
         | 
| 116 | 
            +
              config.converter_registry.unregister :upcase
         | 
| 117 | 
            +
              # now you're free to register your own
         | 
| 118 | 
            +
              config.converter_registry.register :upcase, proc { |v| v.upcase if v }
         | 
| 119 | 
            +
            end
         | 
| 120 | 
            +
            ```
         | 
| 121 | 
            +
             | 
| 114 122 | 
             
            Access registered converters
         | 
| 115 123 | 
             
            ```ruby
         | 
| 116 | 
            -
            decimal_converter = HoneyFormat. | 
| 124 | 
            +
            decimal_converter = HoneyFormat.converter_registry[:decimal]
         | 
| 117 125 | 
             
            decimal_converter.call('1.1') # => 1.1
         | 
| 118 126 | 
             
            ```
         | 
| 119 127 |  | 
| 120 | 
            -
            See [` | 
| 128 | 
            +
            See [`Configuration#default_converters`](https://github.com/buren/honey_format/tree/master/lib/honey_format/configuration.rb#L38) for a complete list of the default ones.
         | 
| 121 129 |  | 
| 122 130 | 
             
            __Row builder__
         | 
| 123 131 |  | 
| @@ -196,7 +204,7 @@ csv = HoneyFormat::CSV.new(csv_string) | |
| 196 204 | 
             
            # Header
         | 
| 197 205 | 
             
            header = csv.header
         | 
| 198 206 | 
             
            header.original # => ["Id", "Username"]
         | 
| 199 | 
            -
            header.columns | 
| 207 | 
            +
            header.columns  # => [:id, :username]
         | 
| 200 208 | 
             
            ```
         | 
| 201 209 |  | 
| 202 210 | 
             
            Define header
         | 
| @@ -213,11 +221,11 @@ HoneyFormat.configure do |config| | |
| 213 221 | 
             
            end
         | 
| 214 222 |  | 
| 215 223 | 
             
            # you can get the default one with
         | 
| 216 | 
            -
            header_converter = HoneyFormat. | 
| 224 | 
            +
            header_converter = HoneyFormat.converter_registry[:header_column]
         | 
| 217 225 | 
             
            header_converter.call('First name') # => "first_name"
         | 
| 218 226 | 
             
            ```
         | 
| 219 227 |  | 
| 220 | 
            -
            Use any  | 
| 228 | 
            +
            Use any converter registry as the header converter
         | 
| 221 229 | 
             
            ```ruby
         | 
| 222 230 | 
             
            csv_string = "Id,Username\n1,buren"
         | 
| 223 231 | 
             
            csv = HoneyFormat::CSV.new(csv_string, header_converter: :upcase)
         | 
| @@ -232,7 +240,7 @@ converter = ->(column) { map.fetch(column, column.downcase) } | |
| 232 240 | 
             
            csv_string = "ID,First^Name\n1,Jacob"
         | 
| 233 241 | 
             
            user = HoneyFormat::CSV.new(csv_string, header_converter: converter).rows.first
         | 
| 234 242 | 
             
            user.first_name # => "Jacob"
         | 
| 235 | 
            -
            user.id | 
| 243 | 
            +
            user.id         # => "1"
         | 
| 236 244 | 
             
            ```
         | 
| 237 245 |  | 
| 238 246 | 
             
            Missing header values
         | 
| @@ -243,6 +251,23 @@ user = csv.rows.first | |
| 243 251 | 
             
            user.column1 # => "val1"
         | 
| 244 252 | 
             
            ```
         | 
| 245 253 |  | 
| 254 | 
            +
            Duplicated header values
         | 
| 255 | 
            +
            ```ruby
         | 
| 256 | 
            +
            csv_string = <<~CSV
         | 
| 257 | 
            +
              email,email,name
         | 
| 258 | 
            +
              john@example.com,jane@example.com,John
         | 
| 259 | 
            +
            CSV
         | 
| 260 | 
            +
            # :deduplicate is the default value
         | 
| 261 | 
            +
            csv = HoneyFormat::CSV.new(csv_string, header_deduplicator: :deduplicate)
         | 
| 262 | 
            +
            user = csv.rows.first
         | 
| 263 | 
            +
            user.email  # => john@example.com
         | 
| 264 | 
            +
            user.email1 # => jane@example.com
         | 
| 265 | 
            +
             | 
| 266 | 
            +
            # you can also choose to raise an error instead
         | 
| 267 | 
            +
            HoneyFormat::CSV.new(csv_string, header_deduplicator: :raise)
         | 
| 268 | 
            +
            # => HoneyFormat::DuplicateHeaderColumnError
         | 
| 269 | 
            +
            ```
         | 
| 270 | 
            +
             | 
| 246 271 | 
             
            If your header contains special chars and/or chars that can't be part of Ruby method names,
         | 
| 247 272 | 
             
            things can get a little awkward..
         | 
| 248 273 | 
             
            ```ruby
         | 
| @@ -280,8 +305,6 @@ end | |
| 280 305 |  | 
| 281 306 | 
             
            You can see all [available errors here](https://www.rubydoc.info/gems/honey_format/HoneyFormat/Errors).
         | 
| 282 307 |  | 
| 283 | 
            -
            If you want to see more usage examples check out the [`examples/`](https://github.com/buren/honey_format/tree/master/examples) and [`spec/`](https://github.com/buren/honey_format/tree/master/spec) directories.
         | 
| 284 | 
            -
             | 
| 285 308 | 
             
            __Skip lines__
         | 
| 286 309 |  | 
| 287 310 | 
             
            > Skip comments and/or other unwanted lines from being parsed.
         | 
| @@ -298,6 +321,31 @@ csv = HoneyFormat::CSV.new(csv_string, skip_lines: regexp) | |
| 298 321 | 
             
            csv.rows.length # => 2
         | 
| 299 322 | 
             
            ```
         | 
| 300 323 |  | 
| 324 | 
            +
            __Matrix__
         | 
| 325 | 
            +
             | 
| 326 | 
            +
            > Use whats under the hood.
         | 
| 327 | 
            +
             | 
| 328 | 
            +
            Actually `HoneyFormat::CSV` is a very thin wrapper around `HoneyFormat::Matrix`.
         | 
| 329 | 
            +
            You can use `Matrix` directly it support all options that aren't specifically tied to parsing a CSV.
         | 
| 330 | 
            +
             | 
| 331 | 
            +
            Example
         | 
| 332 | 
            +
            ```ruby
         | 
| 333 | 
            +
            data = [
         | 
| 334 | 
            +
              %w[name id],
         | 
| 335 | 
            +
              %w[jacob 1]
         | 
| 336 | 
            +
            ]
         | 
| 337 | 
            +
            type_map = {
         | 
| 338 | 
            +
              id: :integer,
         | 
| 339 | 
            +
              name: :upcase
         | 
| 340 | 
            +
            }
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            matrix = HoneyFormat::Matrix.new(data, type_map: { id: :integer, name: :upcase })
         | 
| 343 | 
            +
            matrix.columns   # => [:name, :id]
         | 
| 344 | 
            +
            matrix.rows.to_a # => [#<Row name="JACOB", id=1>]
         | 
| 345 | 
            +
            matrix.to_csv    # => "name,id\nJACOB,1\n"
         | 
| 346 | 
            +
            ```
         | 
| 347 | 
            +
             | 
| 348 | 
            +
            If you want to see more usage examples check out the [`examples/`](https://github.com/buren/honey_format/tree/master/examples) and [`spec/`](https://github.com/buren/honey_format/tree/master/spec) directories and of course [on RubyDoc](https://www.rubydoc.info/gems/honey_format/).
         | 
| 301 349 |  | 
| 302 350 | 
             
            ## CLI
         | 
| 303 351 |  | 
| @@ -330,7 +378,7 @@ $ honey_format input.csv --columns=id,username > output.csv | |
| 330 378 |  | 
| 331 379 | 
             
            ## Benchmark
         | 
| 332 380 |  | 
| 333 | 
            -
            _Note_: This gem, adds some overhead to parsing a CSV string, typically ~5-10%. I've included some benchmarks below, your mileage may vary..
         | 
| 381 | 
            +
            _Note_: This gem, adds some overhead to parsing a CSV string, typically ~5-10%. I've included some benchmarks below, your mileage may vary.. The benchmarks have been run with Ruby 2.5.
         | 
| 334 382 |  | 
| 335 383 | 
             
            204KB (1k lines)
         | 
| 336 384 |  | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/bin/benchmark
    CHANGED
    
    
    
        data/bin/console
    CHANGED
    
    
    
        data/exe/honey_format
    CHANGED
    
    
    
        data/honey_format.gemspec
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 | 
            -
            #  | 
| 2 | 
            -
             | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            lib = File.expand_path('lib', __dir__)
         | 
| 3 4 | 
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 5 | 
             
            require 'honey_format/version'
         | 
| 5 6 |  | 
| @@ -21,10 +22,10 @@ Gem::Specification.new do |spec| | |
| 21 22 |  | 
| 22 23 | 
             
              spec.required_ruby_version = '>= 2.3.0'
         | 
| 23 24 |  | 
| 25 | 
            +
              spec.add_development_dependency 'benchmark-ips'
         | 
| 24 26 | 
             
              spec.add_development_dependency 'bundler', '~> 1.10'
         | 
| 27 | 
            +
              spec.add_development_dependency 'byebug'
         | 
| 25 28 | 
             
              spec.add_development_dependency 'rake', '~> 10.0'
         | 
| 26 | 
            -
              spec.add_development_dependency 'benchmark-ips'
         | 
| 27 29 | 
             
              spec.add_development_dependency 'rspec'
         | 
| 28 30 | 
             
              spec.add_development_dependency 'simplecov'
         | 
| 29 | 
            -
              spec.add_development_dependency 'byebug'
         | 
| 30 31 | 
             
            end
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'optparse'
         | 
| 2 4 | 
             
            require 'honey_format/cli/result_writer'
         | 
| 3 5 |  | 
| @@ -7,9 +9,9 @@ module HoneyFormat | |
| 7 9 | 
             
              # @attr_reader [CLIResultWriter] writer the CLI result writer
         | 
| 8 10 | 
             
              class BenchmarkCLI
         | 
| 9 11 | 
             
                # CSV default test data location
         | 
| 10 | 
            -
                CSV_TEST_DATA_URL = 'https://gist.github.com/buren/b669dd82fa37e37672da2cab33c8a830/raw/54ba14a698941ff61f3b854b66df0a7782c79c85/csv_1000_rows.csv'
         | 
| 12 | 
            +
                CSV_TEST_DATA_URL = 'https://gist.github.com/buren/b669dd82fa37e37672da2cab33c8a830/raw/54ba14a698941ff61f3b854b66df0a7782c79c85/csv_1000_rows.csv'.freeze
         | 
| 11 13 | 
             
                # CSV default test data cache location
         | 
| 12 | 
            -
                CSV_TEST_DATA_CACHE_PATH = '/tmp/honey-format-benchmark-test.csv'
         | 
| 14 | 
            +
                CSV_TEST_DATA_CACHE_PATH = '/tmp/honey-format-benchmark-test.csv'.freeze
         | 
| 13 15 |  | 
| 14 16 | 
             
                attr_reader :writer, :options
         | 
| 15 17 |  | 
| @@ -44,7 +46,7 @@ module HoneyFormat | |
| 44 46 | 
             
                def fetch_default_benchmark_csv
         | 
| 45 47 | 
             
                  cache_path = CSV_TEST_DATA_CACHE_PATH
         | 
| 46 48 |  | 
| 47 | 
            -
                  if File. | 
| 49 | 
            +
                  if File.exist?(cache_path)
         | 
| 48 50 | 
             
                    writer.puts "Cache file found at #{cache_path}.", verbose: true
         | 
| 49 51 | 
             
                    @used_input_path = cache_path
         | 
| 50 52 | 
             
                    return File.read(cache_path)
         | 
| @@ -52,7 +54,7 @@ module HoneyFormat | |
| 52 54 |  | 
| 53 55 | 
             
                  writer.print 'Downloading test data file from GitHub..', verbose: true
         | 
| 54 56 | 
             
                  require 'open-uri'
         | 
| 55 | 
            -
                  open(CSV_TEST_DATA_URL).read.tap do |csv|
         | 
| 57 | 
            +
                  open(CSV_TEST_DATA_URL).read.tap do |csv| # rubocop:disable Security/Open
         | 
| 56 58 | 
             
                    @used_input_path = CSV_TEST_DATA_URL
         | 
| 57 59 | 
             
                    writer.puts 'done!', verbose: true
         | 
| 58 60 | 
             
                    File.write(cache_path, csv)
         | 
| @@ -71,18 +73,18 @@ module HoneyFormat | |
| 71 73 | 
             
                  verbose = false
         | 
| 72 74 |  | 
| 73 75 | 
             
                  OptionParser.new do |parser|
         | 
| 74 | 
            -
                    parser.banner =  | 
| 75 | 
            -
                    parser.default_argv =  | 
| 76 | 
            +
                    parser.banner = 'Usage: bin/benchmark [file.csv] [options]'
         | 
| 77 | 
            +
                    parser.default_argv = argv
         | 
| 76 78 |  | 
| 77 | 
            -
                    parser.on( | 
| 79 | 
            +
                    parser.on('--csv=[file1.csv]', String, 'CSV file(s)') do |value|
         | 
| 78 80 | 
             
                      input_path = value
         | 
| 79 81 | 
             
                    end
         | 
| 80 82 |  | 
| 81 | 
            -
                    parser.on( | 
| 83 | 
            +
                    parser.on('--[no-]verbose', 'Verbose output') do |value|
         | 
| 82 84 | 
             
                      verbose = value
         | 
| 83 85 | 
             
                    end
         | 
| 84 86 |  | 
| 85 | 
            -
                    parser.on( | 
| 87 | 
            +
                    parser.on('--lines-multipliers=[1,10,50]', Array, 'Multiply the rows in the CSV file (default: 1)') do |value|
         | 
| 86 88 | 
             
                      lines_multipliers = value.map do |v|
         | 
| 87 89 | 
             
                        Integer(v).tap do |int|
         | 
| 88 90 | 
             
                          unless int >= 1
         | 
| @@ -92,21 +94,21 @@ module HoneyFormat | |
| 92 94 | 
             
                      end
         | 
| 93 95 | 
             
                    end
         | 
| 94 96 |  | 
| 95 | 
            -
                    parser.on( | 
| 97 | 
            +
                    parser.on('--time=[30]', String, 'Benchmark time (default: 30)') do |value|
         | 
| 96 98 | 
             
                      benchmark_time = Integer(value)
         | 
| 97 99 | 
             
                    end
         | 
| 98 100 |  | 
| 99 | 
            -
                    parser.on( | 
| 101 | 
            +
                    parser.on('--warmup=[30]', String, 'Benchmark warmup (default: 30)') do |value|
         | 
| 100 102 | 
             
                      benchmark_warmup = Integer(value)
         | 
| 101 103 | 
             
                    end
         | 
| 102 104 |  | 
| 103 | 
            -
                    parser.on( | 
| 105 | 
            +
                    parser.on('-h', '--help', 'How to use') do
         | 
| 104 106 | 
             
                      puts parser
         | 
| 105 107 | 
             
                      exit
         | 
| 106 108 | 
             
                    end
         | 
| 107 109 |  | 
| 108 110 | 
             
                    # No argument, shows at tail. This will print an options summary.
         | 
| 109 | 
            -
                    parser.on_tail( | 
| 111 | 
            +
                    parser.on_tail('-h', '--help', 'Show this message') do
         | 
| 110 112 | 
             
                      puts parser
         | 
| 111 113 | 
             
                      exit
         | 
| 112 114 | 
             
                    end
         |