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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +48 -0
- data/LICENSE.txt +22 -0
- data/README.md +264 -0
- data/Rakefile +9 -0
- data/data_maps.gemspec +27 -0
- data/lib/data_maps/concerns/factory.rb +31 -0
- data/lib/data_maps/condition.rb +81 -0
- data/lib/data_maps/converter/affixes.rb +35 -0
- data/lib/data_maps/converter/base.rb +12 -0
- data/lib/data_maps/converter/bool.rb +15 -0
- data/lib/data_maps/converter/keys.rb +23 -0
- data/lib/data_maps/converter/map.rb +24 -0
- data/lib/data_maps/converter/numeric.rb +28 -0
- data/lib/data_maps/converter/ruby.rb +20 -0
- data/lib/data_maps/converter/string.rb +15 -0
- data/lib/data_maps/errors/invalid_data.rb +6 -0
- data/lib/data_maps/executable.rb +33 -0
- data/lib/data_maps/filtered_value.rb +16 -0
- data/lib/data_maps/mapper.rb +25 -0
- data/lib/data_maps/mapping.rb +102 -0
- data/lib/data_maps/statement.rb +80 -0
- data/lib/data_maps/then/base.rb +12 -0
- data/lib/data_maps/then/convert.rb +25 -0
- data/lib/data_maps/then/filter.rb +16 -0
- data/lib/data_maps/then/set.rb +15 -0
- data/lib/data_maps/version.rb +3 -0
- data/lib/data_maps/when/base.rb +12 -0
- data/lib/data_maps/when/comparison.rb +99 -0
- data/lib/data_maps/when/empty.rb +15 -0
- data/lib/data_maps/when/regex.rb +23 -0
- data/lib/data_maps.rb +13 -0
- data/spec/data_maps/concerns/factory_spec.rb +54 -0
- data/spec/data_maps/condition_spec.rb +104 -0
- data/spec/data_maps/converter/affixes_spec.rb +119 -0
- data/spec/data_maps/converter/base_spec.rb +21 -0
- data/spec/data_maps/converter/bool_spec.rb +11 -0
- data/spec/data_maps/converter/keys_spec.rb +25 -0
- data/spec/data_maps/converter/map_spec.rb +45 -0
- data/spec/data_maps/converter/numeric_spec.rb +81 -0
- data/spec/data_maps/converter/ruby_spec.rb +15 -0
- data/spec/data_maps/converter/string_spec.rb +14 -0
- data/spec/data_maps/executable_spec.rb +23 -0
- data/spec/data_maps/filtered_value_spec.rb +12 -0
- data/spec/data_maps/mapper_spec.rb +38 -0
- data/spec/data_maps/mapping_spec.rb +192 -0
- data/spec/data_maps/statement_spec.rb +94 -0
- data/spec/data_maps/then/base_spec.rb +21 -0
- data/spec/data_maps/then/convert_spec.rb +28 -0
- data/spec/data_maps/then/filter_spec.rb +13 -0
- data/spec/data_maps/then/set_spec.rb +11 -0
- data/spec/data_maps/version_spec.rb +8 -0
- data/spec/data_maps/when/base_spec.rb +21 -0
- data/spec/data_maps/when/comparison_spec.rb +129 -0
- data/spec/data_maps/when/empty_spec.rb +29 -0
- data/spec/data_maps/when/regex_spec.rb +31 -0
- data/spec/spec_helper.rb +7 -0
- 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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
+
[](https://travis-ci.org/dino115/data_maps)
|
4
|
+
[](https://codeclimate.com/github/dino115/data_maps)
|
5
|
+
[](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
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,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
|