data_maps 0.1.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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +48 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +264 -0
  9. data/Rakefile +9 -0
  10. data/data_maps.gemspec +27 -0
  11. data/lib/data_maps/concerns/factory.rb +31 -0
  12. data/lib/data_maps/condition.rb +81 -0
  13. data/lib/data_maps/converter/affixes.rb +35 -0
  14. data/lib/data_maps/converter/base.rb +12 -0
  15. data/lib/data_maps/converter/bool.rb +15 -0
  16. data/lib/data_maps/converter/keys.rb +23 -0
  17. data/lib/data_maps/converter/map.rb +24 -0
  18. data/lib/data_maps/converter/numeric.rb +28 -0
  19. data/lib/data_maps/converter/ruby.rb +20 -0
  20. data/lib/data_maps/converter/string.rb +15 -0
  21. data/lib/data_maps/errors/invalid_data.rb +6 -0
  22. data/lib/data_maps/executable.rb +33 -0
  23. data/lib/data_maps/filtered_value.rb +16 -0
  24. data/lib/data_maps/mapper.rb +25 -0
  25. data/lib/data_maps/mapping.rb +102 -0
  26. data/lib/data_maps/statement.rb +80 -0
  27. data/lib/data_maps/then/base.rb +12 -0
  28. data/lib/data_maps/then/convert.rb +25 -0
  29. data/lib/data_maps/then/filter.rb +16 -0
  30. data/lib/data_maps/then/set.rb +15 -0
  31. data/lib/data_maps/version.rb +3 -0
  32. data/lib/data_maps/when/base.rb +12 -0
  33. data/lib/data_maps/when/comparison.rb +99 -0
  34. data/lib/data_maps/when/empty.rb +15 -0
  35. data/lib/data_maps/when/regex.rb +23 -0
  36. data/lib/data_maps.rb +13 -0
  37. data/spec/data_maps/concerns/factory_spec.rb +54 -0
  38. data/spec/data_maps/condition_spec.rb +104 -0
  39. data/spec/data_maps/converter/affixes_spec.rb +119 -0
  40. data/spec/data_maps/converter/base_spec.rb +21 -0
  41. data/spec/data_maps/converter/bool_spec.rb +11 -0
  42. data/spec/data_maps/converter/keys_spec.rb +25 -0
  43. data/spec/data_maps/converter/map_spec.rb +45 -0
  44. data/spec/data_maps/converter/numeric_spec.rb +81 -0
  45. data/spec/data_maps/converter/ruby_spec.rb +15 -0
  46. data/spec/data_maps/converter/string_spec.rb +14 -0
  47. data/spec/data_maps/executable_spec.rb +23 -0
  48. data/spec/data_maps/filtered_value_spec.rb +12 -0
  49. data/spec/data_maps/mapper_spec.rb +38 -0
  50. data/spec/data_maps/mapping_spec.rb +192 -0
  51. data/spec/data_maps/statement_spec.rb +94 -0
  52. data/spec/data_maps/then/base_spec.rb +21 -0
  53. data/spec/data_maps/then/convert_spec.rb +28 -0
  54. data/spec/data_maps/then/filter_spec.rb +13 -0
  55. data/spec/data_maps/then/set_spec.rb +11 -0
  56. data/spec/data_maps/version_spec.rb +8 -0
  57. data/spec/data_maps/when/base_spec.rb +21 -0
  58. data/spec/data_maps/when/comparison_spec.rb +129 -0
  59. data/spec/data_maps/when/empty_spec.rb +29 -0
  60. data/spec/data_maps/when/regex_spec.rb +31 -0
  61. data/spec/spec_helper.rb +7 -0
  62. metadata +199 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ff13a28428388b271443275bd30d17178780d23
4
+ data.tar.gz: 1e501af25f3bed2e788332d01374440ce2a45286
5
+ SHA512:
6
+ metadata.gz: 83fbf366ee2287b51444a37253b285854d669b4e47279fbc45c16a26593c0533d90bb3f899961c0e26774e0b0d15255dd3ea0ac1fc92ef4ca57c8d56edef3c12
7
+ data.tar.gz: 621c5f21a176a058321f76eb758e8d55f71ccfd5851e96bc5d77a71848b652d8d503c7d7e2a42fba5fb32704787d02725da9ff0d77cf34b52726763abaa04842
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .idea/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format documentation
3
+ --backtrace
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 2.1.3
5
+ addons:
6
+ code_climate:
7
+ repo_token: 2111a70b2a7d70a9ec1c1d386e9dbd2f1bceec2cd16524393fcce14c280b571c
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in data_maps.gemspec
4
+ gemspec
5
+
6
+ gem 'codeclimate-test-reporter', group: :test, require: nil
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ data_maps (0.1.0)
5
+ activesupport (~> 3.2.21)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (3.2.21)
11
+ i18n (~> 0.6, >= 0.6.4)
12
+ multi_json (~> 1.0)
13
+ codeclimate-test-reporter (0.4.6)
14
+ simplecov (>= 0.7.1, < 1.0.0)
15
+ diff-lcs (1.2.5)
16
+ docile (1.1.5)
17
+ i18n (0.7.0)
18
+ multi_json (1.10.1)
19
+ rake (10.4.2)
20
+ rspec (3.2.0)
21
+ rspec-core (~> 3.2.0)
22
+ rspec-expectations (~> 3.2.0)
23
+ rspec-mocks (~> 3.2.0)
24
+ rspec-core (3.2.0)
25
+ rspec-support (~> 3.2.0)
26
+ rspec-expectations (3.2.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.2.0)
29
+ rspec-mocks (3.2.0)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.2.0)
32
+ rspec-support (3.2.1)
33
+ simplecov (0.9.1)
34
+ docile (~> 1.1.0)
35
+ multi_json (~> 1.0)
36
+ simplecov-html (~> 0.8.0)
37
+ simplecov-html (0.8.0)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ bundler (~> 1.7)
44
+ codeclimate-test-reporter
45
+ data_maps!
46
+ rake (~> 10.0)
47
+ rspec (~> 3.2)
48
+ simplecov (~> 0.9.1)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Axel Wahlen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,264 @@
1
+ DataMaps
2
+ =================
3
+ [![Build Status](https://travis-ci.org/dino115/data_maps.svg?branch=master)](https://travis-ci.org/dino115/data_maps)
4
+ [![Code Climate](https://codeclimate.com/github/dino115/data_maps/badges/gpa.svg)](https://codeclimate.com/github/dino115/data_maps)
5
+ [![Test Coverage](https://codeclimate.com/github/dino115/data_maps/badges/coverage.svg)](https://codeclimate.com/github/dino115/data_maps)
6
+
7
+ Create great mappings to convert structured data into your own format!
8
+
9
+ **Attention:** This gem is currently under development and can't be used yet!
10
+
11
+ ## Installation
12
+
13
+ Add this line to your applications' Gemfile:
14
+
15
+ ```ruby
16
+ gem 'data_maps'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install data_maps
26
+
27
+ ## Usage
28
+
29
+ ### Mapper
30
+ The DataMaps::Mapper converts data from a ruby hash to another.
31
+
32
+ ```ruby
33
+ mapper = DataMaps::Mapper.new(mapping)
34
+
35
+ converted_data = your_data.map do |data_row|
36
+ mapper.convert(data_row)
37
+ end
38
+ ```
39
+
40
+ ### Mapping
41
+ Create mappings.
42
+
43
+ #### Simple field mapping
44
+ ```ruby
45
+ mapping = DataMaps::Mapping.new({
46
+ 'field' => {
47
+ from: 'source'
48
+ }
49
+ # or simple: 'field' => 'source'
50
+ })
51
+ ```
52
+
53
+ #### Conditions
54
+ Conditions must always have a when and then command. All condition statements are executed procedural.
55
+ The only exception is when using `then: { filter: true }`, then the execution breaks immediately and removes the whole field from result data.
56
+
57
+ ```ruby
58
+ 'field' => {
59
+ from: 'source' # or array of source fields
60
+ conditions: [
61
+ { when: { empty: true }, then: { set: 'something' },
62
+ { when: { regex: /[1-9]{5}/i }, then: { convert: { numeric: 'Integer' } } }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ ##### Possible when's
68
+
69
+ - **When: empty**
70
+ Possible options for the empty conditions are `true` or `false`.
71
+ The condition is true when `data.empty? == result`
72
+
73
+ ```ruby
74
+ empty: true # or false
75
+ ```
76
+ - **When: regex**
77
+ Define a regular expression condition.
78
+ The condition is true when `data.match regex`. Only works with strings.
79
+
80
+ ```ruby
81
+ regex: /[a-z]/i
82
+ ```
83
+ - **When: gt, gte**
84
+ Check if data is *greater* or *greater or equal* than the given value. Only works with comparable objects.
85
+
86
+ ```ruby
87
+ gt: 5
88
+ gte 5
89
+ ```
90
+ - **When: lt, lte**
91
+ Check if data is *lower* or *lower or equal* than the given value. Only works with comparable objects.
92
+
93
+ ```ruby
94
+ lt: 5
95
+ lte: 5
96
+ ```
97
+ - **When: eq, neq**
98
+ Check if data is *equal* or *not equal* to the given value. Only works with comparable objects.
99
+
100
+ ```ruby
101
+ eq: 10
102
+ neq: 'a-value'
103
+ ```
104
+ - **When: in, nin**
105
+ Check if data is *in* or *not in* the set of given values. Doesn't work for a collection of values.
106
+
107
+ ```ruby
108
+ in: ['a', 'b', 'c']
109
+ nin: ['x', 'y', 'z']
110
+ ```
111
+ - **When: custom**
112
+ Define your own condition class by defining them in the `DataMaps::When` module.
113
+ Your `When` must implement a `execute` method which returns `true` or `false`.
114
+ You have to extend the `DataMaps::When::Base` class. Then all options are available via the `option` attribute reader.
115
+
116
+ ```ruby
117
+ class DataMaps::When::IsZip < DataMaps::When::Base
118
+ def execute(data)
119
+ !!data.match(/\d{5}/)
120
+ end
121
+ end
122
+ ```
123
+
124
+ ```ruby
125
+ is_zip: true # option isn't used, you can pass anything, for example and readability true
126
+ ```
127
+
128
+ ##### Possible then's
129
+
130
+ - **Then: set**
131
+ Set the value to given value.
132
+
133
+ ```ruby
134
+ set: 'to this value'
135
+ ```
136
+ - **Then: convert**
137
+ Apply the configured converter. See converter section for more information.
138
+
139
+ ```ruby
140
+ convert: {
141
+ numeric: 'Integer'
142
+ }
143
+ ```
144
+ - **Then: filter**
145
+ When this is set to true then the whole field will filtered.
146
+
147
+ ```ruby
148
+ filter: true
149
+ ```
150
+ - **Then: custom**
151
+ Define your own *then* by defining them in the `DataMaps::Then` module.
152
+ Your `Then` must implement a `execute` method. The return of this method is set as data.
153
+ You have to extend the `DataMaps::Then::Base` class. Then all options are available via the `option` attribute reader.
154
+
155
+ ```ruby
156
+ class DataMaps::Then::SendEmail < DataMaps::Then::Base
157
+ def execute(data)
158
+ MyFramework::Email.send(to: option)
159
+ data
160
+ end
161
+ end
162
+ ```
163
+
164
+ ```ruby
165
+ send_email: me@example.com
166
+ ```
167
+
168
+ #### Converter
169
+ Apply one or many converters to the input data. Converters applied procedural.
170
+
171
+ ```ruby
172
+ 'field' => {
173
+ from: 'source',
174
+ convert: {
175
+ map: {
176
+ 1: 'A',
177
+ 2: 'B'
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ##### Possible converter
184
+
185
+ - **Converter: map**
186
+ A simple value mapping. Maps are converted to a `HashWithIndifferentAccess`.
187
+ Works with flat values, hashes and arrays.
188
+ For arrays and hashes it returns nil if the value is not in the mapping. For flat values it returns the original data.
189
+
190
+ ```ruby
191
+ map: {
192
+ from: to
193
+ }
194
+ ```
195
+ - **Converter: numeric**
196
+ Cast data to a numeric value. Possible options are 'Integer', 'Float' or a number, then it is casted to float and rounded. Doesn't work with collections.
197
+ Can raise an error if the value is not convertable.
198
+
199
+ ```ruby
200
+ numeric: 'Integer'
201
+ numeric: 'Float'
202
+ numeric: 2
203
+ ```
204
+ - **Converter: String**
205
+ Cast explicit to string. Doesn't work with collections.
206
+ Can raise error if the value is not convertable.
207
+
208
+ ```ruby
209
+ string: true
210
+ ```
211
+ - **Converter: Boolean**
212
+ Cast explicit to bool (by double negotiation). Doesn't work with collections.
213
+ Can return unexpected values, e.g. a double negotiated empty array is true! `!![] #=> true`
214
+
215
+ ```ruby
216
+ bool: true
217
+ ```
218
+ - **Converter: keys**
219
+ This maps the hash keys when the input data is a hash or when you select multiple *from* fields. Only works with hashes.
220
+ Return the original data when the data isn't a hash.
221
+
222
+ ```ruby
223
+ keys: {
224
+ 'address1' => 'street'
225
+ }
226
+ ```
227
+ - **Converter: Prefix**
228
+ This prefixes the data with a given value. Call `to_s` on data and always returns a string.
229
+
230
+ ```ruby
231
+ prefix: '$'
232
+ ```
233
+ - **Converter: Postfix**
234
+ This postfixes the data with a given value. Call `to_s` on data and always returns a string.
235
+
236
+ ```ruby
237
+ postfix: '€'
238
+ ```
239
+ - **Converter: ruby**
240
+ Apply any method on the current data object.
241
+
242
+ ```ruby
243
+ ruby: :upcase
244
+ ruby: [:slice, 5]
245
+ ruby: [:join, ', ']
246
+ ```
247
+ - **Converter: custom**
248
+ Define your own *converter* by defining them in the `DataMaps::Converter` module.
249
+ Your `Converter` must implement an `execute` method. The return of this method is set as new data.
250
+ You have to extend the `DataMaps::Converter::Base` class. Then all options are available via the `option` attribute reader.
251
+
252
+ ```ruby
253
+ class DataMaps::Converter::ToPersonObject < DataMaps::Converter::Base
254
+ def execute(data)
255
+ Person.new(data, option)
256
+ end
257
+ end
258
+ ```
259
+
260
+ ```ruby
261
+ to_person_object: { as: :importer } # passed value are available with option
262
+ ```
263
+
264
+ Have fun using the `DataMaps` gem :)
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ task :default => :spec
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ rescue LoadError
8
+ puts 'rspec isn\'t available'
9
+ end
data/data_maps.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'data_maps/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'data_maps'
8
+ spec.version = DataMaps::VERSION
9
+ spec.authors = ['Axel Wahlen']
10
+ spec.email = ['axel.wahlen@mixxt.de']
11
+ spec.summary = %q{ Maps data to another structure through a mapping }
12
+ spec.description = %q{ Maps data to another structure through a mapping }
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'activesupport', '~> 3.2.21'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.7'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.2'
26
+ spec.add_development_dependency 'simplecov', '~> 0.9.1'
27
+ end
@@ -0,0 +1,31 @@
1
+ module DataMaps
2
+ module Concerns
3
+ module Factory
4
+ # Factory to create an instance from a class in this module
5
+ #
6
+ # @param [String] name
7
+ # @param [mixed] option
8
+ # @return [Class]
9
+ def factory(name, option)
10
+ name = name.to_s.classify
11
+ klass_name = "#{self.name}::#{name}"
12
+ raise ArgumentError.new("No class '#{klass_name}' exists.") unless self.constants.include?(name.to_sym)
13
+
14
+ klass = klass_name.constantize
15
+ klass.new(option)
16
+ end
17
+
18
+ # Helper method to create class from a mapping_hash
19
+ #
20
+ # @param [Hash] mapping
21
+ # @return [Array] of factorized classes
22
+ def create_from_map(mapping)
23
+ raise ArgumentError.new("#{self.name} mapping has to be an hash") unless mapping.is_a?(Hash)
24
+
25
+ mapping.map do |name, option|
26
+ self.factory(name, option)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ module DataMaps
2
+ # A condition
3
+ #
4
+ # @since 0.0.1
5
+ # @attr_reader [Array] whens
6
+ # @attr_reader [Array] thens
7
+ class Condition
8
+ attr_reader :whens, :thens
9
+
10
+ # Helper method to create conditions from a mapping
11
+ #
12
+ # @param [Array] mapping
13
+ #
14
+ # @return [Array] of Condition
15
+ def self.create_from_map(mapping)
16
+ raise ArgumentError.new('Conditions mapping has to be an array') unless mapping.is_a?(Array)
17
+
18
+ mapping.map do |condition|
19
+ self.new(
20
+ DataMaps::When.create_from_map(condition[:when]),
21
+ DataMaps::Then.create_from_map(condition[:then])
22
+ )
23
+ end
24
+ end
25
+
26
+ # Initializer for a Condition
27
+ #
28
+ # @param [Array] whens an array of when's
29
+ # @param [Array] thens an array of then's
30
+ def initialize(whens, thens)
31
+ raise ArgumentError.new('Whens must be an array of DataMaps::When') unless DataMaps::When::Base.valid_collection?(whens)
32
+ raise ArgumentError.new('Thens must be an array of DataMaps::Then') unless DataMaps::Then::Base.valid_collection?(thens)
33
+
34
+ @whens = whens
35
+ @thens = thens
36
+ end
37
+
38
+ # Helper method to indicate if this condition can break execution
39
+ #
40
+ # @return [Bool]
41
+ def can_break?
42
+ thens.any?{ |t| t.is_a?(DataMaps::Then::Filter) }
43
+ end
44
+
45
+ # Execute this condition with given data
46
+ #
47
+ # @param [mixed] data The given data
48
+ # @return [mixed] data The original or modified data for the next step
49
+ def execute(data)
50
+ if check(data)
51
+ if can_break?
52
+ DataMaps::FilteredValue.new(data)
53
+ else
54
+ result(data)
55
+ end
56
+ else
57
+ data
58
+ end
59
+ end
60
+
61
+ # Check all whens on data
62
+ #
63
+ # @param [mixed] data The given data
64
+ # @return [mixed] data The original or modified data for the next step
65
+ def check(data)
66
+ whens.all? { |w| w.execute data }
67
+ end
68
+
69
+ # Apply the thens on data
70
+ #
71
+ # @param [mixed] data The given data
72
+ # @return [mixed] data The original or modified data for the next step
73
+ def result(data)
74
+ thens.each do |t|
75
+ data = t.execute(data)
76
+ end
77
+
78
+ data
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,35 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Adds a prefix to the given data
4
+ #
5
+ # @since 0.0.1
6
+ class Prefix < Base
7
+ # The execute method to adds a prefix to the given data
8
+ #
9
+ # @param [mixed] data
10
+ def execute(data)
11
+ case data
12
+ when Array then data.map{ |v| "#{option}#{v}" }
13
+ when Hash then Hash[data.map{ |k,v| [k,"#{option}#{v}"] }]
14
+ else "#{option}#{data}"
15
+ end
16
+ end
17
+ end
18
+
19
+ # Adds a postfix to the given data
20
+ #
21
+ # @since 0.0.1
22
+ class Postfix < Base
23
+ # The execute method to adds a postfix to the given data
24
+ #
25
+ # @param [mixed] data
26
+ def execute(data)
27
+ case data
28
+ when Array then data.map{ |v| "#{v}#{option}" }
29
+ when Hash then Hash[data.map{ |k,v| [k,"#{v}#{option}"] }]
30
+ else "#{data}#{option}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ module DataMaps
2
+ module Converter
3
+ extend DataMaps::Concerns::Factory
4
+
5
+ # Base class for converter
6
+ #
7
+ # @since 0.0.1
8
+ # @abstract
9
+ class Base < DataMaps::Executable
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Converts numeric values
4
+ #
5
+ # @since 0.0.1
6
+ class Bool < Base
7
+ # The execute method to convert the given data into string
8
+ #
9
+ # @param [mixed] data
10
+ def execute(data)
11
+ !!data
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Converts numeric values
4
+ #
5
+ # @since 0.0.1
6
+ class Keys < Base
7
+ # The after initialize callback
8
+ def after_initialize
9
+ @option = option.with_indifferent_access
10
+ end
11
+
12
+ # The execute method to convert the keys of given data
13
+ #
14
+ # @param [mixed] data
15
+ def execute(data)
16
+ case data
17
+ when Hash then Hash[data.map{ |k,v| [option[k] || k, v] }]
18
+ else data
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Map values
4
+ #
5
+ # @since 0.0.1
6
+ class Map < Base
7
+ # The after initialize callback
8
+ def after_initialize
9
+ @option = option.with_indifferent_access
10
+ end
11
+
12
+ # The execute method to convert the given data
13
+ #
14
+ # @param [mixed] data
15
+ def execute(data)
16
+ case data
17
+ when Array then data.map{ |d| option[d] }
18
+ when Hash then Hash[data.map{ |k,v| [k, option[v]] }]
19
+ else option[data] || data
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Converts numeric values
4
+ #
5
+ # @since 0.0.1
6
+ class Numeric < Base
7
+ # The execute method to convert the given data
8
+ #
9
+ # @param [mixed] data
10
+ def execute(data)
11
+ raise DataMaps::Errors::InvalidDataError.new("The given data is not a numeric: #{data}") unless is_numeric?(data)
12
+
13
+ case option
14
+ when 'Integer' then data.to_i
15
+ when 'Float' then data.to_f
16
+ when Integer then data.to_f.round(option)
17
+ else data
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def is_numeric?(data)
24
+ true if Float(data) rescue false
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module DataMaps
2
+ module Converter
3
+ # Ruby method converter
4
+ #
5
+ # @since 0.0.1
6
+ class Ruby < Base
7
+ # After initialize callback
8
+ def after_initialize
9
+ @option = Array(option)
10
+ end
11
+
12
+ # The execute method to convert the given data
13
+ #
14
+ # @param [mixed] data
15
+ def execute(data)
16
+ data.respond_to?(option.first) ? data.send(*option) : data
17
+ end
18
+ end
19
+ end
20
+ end