eco-helpers 1.4.2 → 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +146 -3
- data/LICENSE +21 -0
- data/eco-helpers.gemspec +11 -10
- data/lib/eco/api.rb +3 -0
- data/lib/eco/api/common.rb +5 -1
- data/lib/eco/api/common/base_loader.rb +54 -0
- data/lib/eco/api/common/class_auto_loader.rb +109 -0
- data/lib/eco/api/common/class_helpers.rb +33 -0
- data/lib/eco/api/common/class_hierarchy.rb +1 -1
- data/lib/eco/api/common/class_meta_basics.rb +16 -0
- data/lib/eco/api/common/loaders.rb +13 -0
- data/lib/eco/api/common/loaders/error_handler.rb +41 -0
- data/lib/eco/api/common/loaders/parser.rb +127 -0
- data/lib/eco/api/common/loaders/policy.rb +25 -0
- data/lib/eco/api/common/loaders/use_case.rb +40 -0
- data/lib/eco/api/common/people/default_parsers.rb +5 -10
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +13 -23
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +20 -35
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +15 -26
- data/lib/eco/api/common/people/default_parsers/freemium_parser.rb +20 -0
- data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +26 -0
- data/lib/eco/api/common/people/default_parsers/multi_parser.rb +15 -27
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +14 -19
- data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +31 -0
- data/lib/eco/api/common/people/default_parsers/send_invites_parser.rb +15 -24
- data/lib/eco/api/common/people/entries.rb +54 -24
- data/lib/eco/api/common/people/entry_factory.rb +18 -15
- data/lib/eco/api/common/people/person_attribute_parser.rb +29 -12
- data/lib/eco/api/common/people/person_entry.rb +308 -216
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +5 -2
- data/lib/eco/api/common/people/person_parser.rb +52 -19
- data/lib/eco/api/common/session/base_session.rb +3 -6
- data/lib/eco/api/common/session/environment.rb +2 -23
- data/lib/eco/api/common/session/logger.rb +4 -0
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +2 -0
- data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +9 -1
- data/lib/eco/api/common/version_patches/exception.rb +22 -0
- data/lib/eco/api/custom.rb +13 -0
- data/lib/eco/api/custom/error_handler.rb +20 -0
- data/lib/eco/api/custom/namespace.rb +7 -0
- data/lib/eco/api/custom/parser.rb +50 -0
- data/lib/eco/api/custom/policy.rb +28 -0
- data/lib/eco/api/custom/use_case.rb +16 -0
- data/lib/eco/api/error.rb +1 -0
- data/lib/eco/api/error/handlers.rb +10 -3
- data/lib/eco/api/microcases.rb +35 -0
- data/lib/eco/api/microcases/account_excluded.rb +24 -0
- data/lib/eco/api/microcases/append_usergroups.rb +19 -0
- data/lib/eco/api/microcases/core_excluded.rb +20 -0
- data/lib/eco/api/microcases/fix_default_group.rb +34 -0
- data/lib/eco/api/microcases/fix_filter_tags.rb +42 -0
- data/lib/eco/api/microcases/people_cache.rb +17 -0
- data/lib/eco/api/microcases/people_load.rb +59 -0
- data/lib/eco/api/microcases/people_refresh.rb +31 -0
- data/lib/eco/api/microcases/people_search.rb +65 -0
- data/lib/eco/api/microcases/refresh_abilities.rb +19 -0
- data/lib/eco/api/microcases/refresh_default_tag.rb +27 -0
- data/lib/eco/api/microcases/s3upload_targets.rb +39 -0
- data/lib/eco/api/microcases/set_account.rb +20 -0
- data/lib/eco/api/microcases/set_core.rb +18 -0
- data/lib/eco/api/microcases/set_core_with_supervisor.rb +23 -0
- data/lib/eco/api/microcases/set_supervisor.rb +30 -0
- data/lib/eco/api/microcases/strict_search.rb +19 -0
- data/lib/eco/api/microcases/with_each.rb +27 -0
- data/lib/eco/api/microcases/with_each_leaver.rb +24 -0
- data/lib/eco/api/microcases/with_each_present.rb +30 -0
- data/lib/eco/api/microcases/with_each_starter.rb +30 -0
- data/lib/eco/api/microcases/with_each_subordinate.rb +34 -0
- data/lib/eco/api/microcases/with_supervisor.rb +36 -0
- data/lib/eco/api/organization/people.rb +72 -35
- data/lib/eco/api/organization/presets_factory.rb +13 -4
- data/lib/eco/api/organization/presets_reference.json +9 -1
- data/lib/eco/api/organization/presets_values.json +4 -1
- data/lib/eco/api/policies.rb +11 -7
- data/lib/eco/api/session.rb +62 -29
- data/lib/eco/api/session/batch.rb +2 -45
- data/lib/eco/api/session/batch/base_policy.rb +7 -6
- data/lib/eco/api/session/batch/errors.rb +28 -4
- data/lib/eco/api/session/batch/feedback.rb +7 -1
- data/lib/eco/api/session/batch/job.rb +40 -23
- data/lib/eco/api/session/batch/jobs.rb +9 -4
- data/lib/eco/api/session/batch/jobs_groups.rb +1 -1
- data/lib/eco/api/session/batch/request_stats.rb +95 -58
- data/lib/eco/api/session/batch/status.rb +35 -31
- data/lib/eco/api/session/config.rb +106 -44
- data/lib/eco/api/session/config/api.rb +132 -7
- data/lib/eco/api/session/config/apis.rb +24 -25
- data/lib/eco/api/session/config/logger.rb +2 -2
- data/lib/eco/api/session/config/post_launch.rb +1 -1
- data/lib/eco/api/session/config/workflow.rb +8 -7
- data/lib/eco/api/usecases.rb +47 -33
- data/lib/eco/api/usecases/backup/append_usergroups_case.rb +36 -0
- data/lib/eco/api/usecases/backup/create_case.rb +104 -0
- data/lib/eco/api/usecases/backup/create_details_case.rb +31 -0
- data/lib/eco/api/usecases/backup/create_details_with_supervisor_case.rb +48 -0
- data/lib/eco/api/usecases/backup/hris_case.rb +124 -0
- data/lib/eco/api/usecases/backup/set_default_tag_case.rb +49 -0
- data/lib/eco/api/usecases/backup/set_supervisor_case.rb +41 -0
- data/lib/eco/api/usecases/backup/transfer_account_case.rb +90 -0
- data/lib/eco/api/usecases/backup/update_case.rb +112 -0
- data/lib/eco/api/usecases/backup/update_details_case.rb +64 -0
- data/lib/eco/api/usecases/backup/upsert_case.rb +114 -0
- data/lib/eco/api/usecases/base_case.rb +2 -0
- data/lib/eco/api/usecases/base_io.rb +3 -3
- data/lib/eco/api/usecases/default_cases.rb +23 -53
- data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +10 -31
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +23 -47
- data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +56 -43
- data/lib/eco/api/usecases/default_cases/create_case.rb +15 -101
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +11 -26
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +12 -43
- data/lib/eco/api/usecases/default_cases/delete_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/delete_trans_case.rb +14 -0
- data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +10 -21
- data/lib/eco/api/usecases/default_cases/hris_case.rb +23 -120
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +10 -23
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +11 -25
- data/lib/eco/api/usecases/default_cases/new_id_case0.rb +14 -0
- data/lib/eco/api/usecases/default_cases/org_data_convert_case.rb +83 -0
- data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +30 -0
- data/lib/eco/api/usecases/default_cases/refresh_case.rb +7 -20
- data/lib/eco/api/usecases/default_cases/reinvite_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/reinvite_trans_case.rb +17 -0
- data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +17 -0
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +9 -19
- data/lib/eco/api/usecases/default_cases/restore_db_case.rb +92 -0
- data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +32 -40
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +15 -33
- data/lib/eco/api/usecases/default_cases/switch_supervisor_case.rb +66 -57
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -44
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +40 -55
- data/lib/eco/api/usecases/default_cases/transfer_account_case.rb +264 -84
- data/lib/eco/api/usecases/default_cases/update_case.rb +15 -109
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +14 -61
- data/lib/eco/api/usecases/default_cases/upsert_case.rb +16 -111
- data/lib/eco/api/usecases/use_case_io.rb +9 -9
- data/lib/eco/cli/config.rb +10 -2
- data/lib/eco/cli/config/default.rb +2 -1
- data/lib/eco/cli/config/default/input_filters.rb +58 -0
- data/lib/eco/cli/config/default/options.rb +60 -25
- data/lib/eco/cli/config/default/people.rb +4 -4
- data/lib/eco/cli/config/default/people_filters.rb +108 -0
- data/lib/eco/cli/config/default/usecases.rb +69 -32
- data/lib/eco/cli/config/default/workflow.rb +37 -27
- data/lib/eco/cli/config/filters.rb +50 -0
- data/lib/eco/cli/config/filters/input_filters.rb +29 -0
- data/lib/eco/cli/config/filters/people_filters.rb +29 -0
- data/lib/eco/cli/config/help.rb +49 -0
- data/lib/eco/cli/config/options_set.rb +17 -1
- data/lib/eco/cli/config/use_cases.rb +79 -53
- data/lib/eco/cli/scripting.rb +10 -2
- data/lib/eco/cli/scripting/args_helpers.rb +25 -15
- data/lib/eco/cli/scripting/argument.rb +1 -0
- data/lib/eco/cli/scripting/arguments.rb +1 -1
- data/lib/eco/csv.rb +8 -3
- data/lib/eco/csv/table.rb +1 -1
- data/lib/eco/data/crypto/encryption.rb +3 -0
- data/lib/eco/data/files/helpers.rb +6 -1
- data/lib/eco/language/match.rb +19 -9
- data/lib/eco/language/match_modifier.rb +13 -5
- data/lib/eco/language/models/collection.rb +77 -56
- data/lib/eco/language/models/parser_serializer.rb +39 -15
- data/lib/eco/version.rb +1 -1
- metadata +149 -63
- data/lib/eco/api/session/task.rb +0 -175
- data/lib/eco/api/usecases/default_case.rb +0 -19
- data/lib/eco/api/usecases/default_cases/delete_case.rb +0 -32
- data/lib/eco/api/usecases/default_cases/recover_db_case.rb +0 -98
- data/lib/eco/api/usecases/default_cases/refresh_presets_case.rb +0 -26
- data/lib/eco/api/usecases/default_cases/reinvite_case.rb +0 -41
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +0 -38
- data/lib/eco/cli/config/default/filters.rb +0 -70
- data/lib/eco/cli/config/people_filters.rb +0 -38
data/lib/eco/csv.rb
CHANGED
@@ -15,9 +15,14 @@ module Eco
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def read(file, **kargs)
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
kargs = {headers: true, skip_blanks: true}.merge(kargs)
|
19
|
+
|
20
|
+
args = [file].tap do |arg|
|
21
|
+
coding = Eco::API::Common::Session::FileManager.encoding(file)
|
22
|
+
arg.push("rb:bom|utf-8") if coding == "bom"
|
23
|
+
end
|
24
|
+
|
25
|
+
out = super(*args, **kargs).reject do |row|
|
21
26
|
values = row.to_hash.values
|
22
27
|
values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
|
23
28
|
end
|
data/lib/eco/csv/table.rb
CHANGED
@@ -3,7 +3,7 @@ module Eco
|
|
3
3
|
class CSV
|
4
4
|
class Table < ::CSV::Table
|
5
5
|
|
6
|
-
# @param
|
6
|
+
# @param input [Array<Row>, Array<Array>, Eco::CSV::Table, ::CSV::Table]
|
7
7
|
# - when `Array<Array>` => all `rows` as arrays where first array is the **header**
|
8
8
|
def initialize(input)
|
9
9
|
super(to_rows_array(input))
|
@@ -7,6 +7,7 @@ require_relative '../../cli/scripting'
|
|
7
7
|
|
8
8
|
# see some ramblings here: http://distributed-frostbite.blogspot.com/2010/06/file-encryption-in-ruby-with-openssl.html
|
9
9
|
|
10
|
+
|
10
11
|
def run! # this will run only if called from command line (not when require'd nor load'd)
|
11
12
|
include Eco::CLI::Scripting
|
12
13
|
include Eco::Data::Crypto
|
@@ -145,6 +146,8 @@ module Eco
|
|
145
146
|
str_c += cipher.final
|
146
147
|
return str_c
|
147
148
|
#EncryptedData.new({content: str_c, key: key, iv: iv})
|
149
|
+
|
150
|
+
|
148
151
|
end
|
149
152
|
def aes256_decrypt(data, key: , iv: , block_octets: BLOCK_OCTETS)
|
150
153
|
block_bits = block_bits * 8
|
@@ -62,8 +62,13 @@ module Eco
|
|
62
62
|
File.write(dest_file, File.read(source_file))
|
63
63
|
end
|
64
64
|
|
65
|
+
def file_empty?(path)
|
66
|
+
return true if !File.file?(path)
|
67
|
+
File.zero?(path)
|
68
|
+
end
|
69
|
+
|
65
70
|
def has_bom?(path)
|
66
|
-
return false if !path
|
71
|
+
return false if !path || file_empty?(path)
|
67
72
|
File.open(path, "rb") do |f|
|
68
73
|
bytes = f.read(3)
|
69
74
|
return bytes.unpack("C*") == [239, 187, 191]
|
data/lib/eco/language/match.rb
CHANGED
@@ -1,30 +1,40 @@
|
|
1
1
|
module Eco
|
2
2
|
module Language
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
def match?(value, at, mode = MatchModifier.new, depth: 0)
|
5
|
+
out_match = ->(v) { match?(v, at, mode, depth: depth + 1) }
|
6
|
+
in_match = ->(a) { match?(value, a, mode, depth: depth + 1) }
|
7
|
+
indent_msg = ->(m) { puts (" " * depth) + m if mode.debug? }
|
6
8
|
|
7
9
|
case
|
8
10
|
when mode.reverse?
|
9
|
-
|
11
|
+
indent_msg.call("reverse value #{value} <--> at: #{at}")
|
12
|
+
match?(at , value, mode.new.reset_reverse, depth: depth + 1)
|
10
13
|
when mode.pattern?
|
14
|
+
indent_msg.call("at to pattern: #{at}")
|
11
15
|
at = mode.to_regex(at)
|
12
|
-
|
16
|
+
match?(value, at, mode.new.reset_pattern, depth: depth + 1)
|
13
17
|
when value.is_a?(Array)
|
18
|
+
indent_msg.call("array #{value} value.#{mode.any?? "any?" : "all?"} match(v_item, at) at: #{at}")
|
14
19
|
return value.any?(&out_match) if mode.any?
|
15
|
-
|
20
|
+
value.all?(&out_match) # defaults to EVERY
|
16
21
|
when at.is_a?(Array)
|
22
|
+
indent_msg.call("array #{at} at.#{mode.and?? "all?" : "any?"} match(value, at_item). value: #{value}")
|
17
23
|
return at.all?(&in_match) if mode.and?
|
18
|
-
|
24
|
+
at.any?(&in_match) # defaullts to OR
|
19
25
|
when at.is_a?(Regexp)
|
20
|
-
|
26
|
+
indent_msg.call("(#{at.inspect}) at.match?(value); value: #{value}")
|
27
|
+
at.match?(value)
|
21
28
|
when value.is_a?(Regexp)
|
22
|
-
|
29
|
+
indent_msg.call("(#{value.inspect}) value.match?(at); at: #{at}")
|
30
|
+
value.match?(at)
|
23
31
|
else # final compare
|
32
|
+
indent_msg.call("-- final -- mode: #{mode.to_a}; value: #{value}; at: #{at}")
|
24
33
|
m = (value == at) ||
|
25
34
|
(mode.insensitive? && at&.downcase == value&.downcase)
|
26
35
|
(mode.not?) ? !m : m
|
27
36
|
end
|
28
37
|
end
|
38
|
+
|
29
39
|
end
|
30
40
|
end
|
@@ -60,6 +60,10 @@ module Eco
|
|
60
60
|
self < self.mode - (NOT_MODE | YES_MODE)
|
61
61
|
end
|
62
62
|
|
63
|
+
def debug
|
64
|
+
self.push(:debug)
|
65
|
+
end
|
66
|
+
|
63
67
|
def pattern
|
64
68
|
self.push(:pattern)
|
65
69
|
end
|
@@ -116,24 +120,28 @@ module Eco
|
|
116
120
|
self.push(:not)
|
117
121
|
end
|
118
122
|
|
123
|
+
def debug?
|
124
|
+
mode.any? {|m| m == :debug}
|
125
|
+
end
|
126
|
+
|
119
127
|
def pattern?
|
120
|
-
mode.any? {
|
128
|
+
mode.any? {|m| PATTERN_MODE.include?(m)}
|
121
129
|
end
|
122
130
|
|
123
131
|
def value?
|
124
|
-
mode.any? {
|
132
|
+
mode.any? {|m| VALUE_MODE.include?(m)}
|
125
133
|
end
|
126
134
|
|
127
135
|
def reverse?
|
128
|
-
mode.any? {
|
136
|
+
mode.any? {|m| REVERSE_MODE.include?(m)}
|
129
137
|
end
|
130
138
|
|
131
139
|
def non_reverse?
|
132
|
-
mode.any? {
|
140
|
+
mode.any? {|m| NON_REVERSE_MODE.include?(m)}
|
133
141
|
end
|
134
142
|
|
135
143
|
def any?
|
136
|
-
mode.any? {
|
144
|
+
mode.any? {|m| ANY_MODE.include?(m)}
|
137
145
|
end
|
138
146
|
|
139
147
|
def some?
|
@@ -4,19 +4,19 @@ module Eco
|
|
4
4
|
class Collection
|
5
5
|
include Enumerable
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
BASIC_METHODS = ["present", "empty", "present_all?", "present_some?"]
|
8
|
+
EXTENDED_METHODS = BASIC_METHODS + ["exclude", "remove", "attr", "attr?", "attrs", "unique_attrs", "contains"]
|
9
9
|
|
10
10
|
class << self
|
11
11
|
|
12
|
-
def
|
12
|
+
def attr_presence(*attrs)
|
13
13
|
block = ->(method) { attrs_create_method(attrs, method) }
|
14
|
-
|
14
|
+
BASIC_METHODS.each(&block)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def attr_collection(*attrs)
|
18
18
|
block = ->(method) { attrs_create_method(attrs, method) }
|
19
|
-
|
19
|
+
EXTENDED_METHODS.each(&block)
|
20
20
|
end
|
21
21
|
|
22
22
|
def attrs_create_method(attrs, method)
|
@@ -35,8 +35,6 @@ module Eco
|
|
35
35
|
|
36
36
|
end
|
37
37
|
|
38
|
-
#attr_reader :items
|
39
|
-
|
40
38
|
def initialize(data = [], klass:, factory: nil, handy: Eco::Assets::Language.new)
|
41
39
|
raise "Raise klass required, given: #{klass}" if !klass
|
42
40
|
@klass = klass
|
@@ -45,6 +43,15 @@ module Eco
|
|
45
43
|
@items = to_klass(data)
|
46
44
|
end
|
47
45
|
|
46
|
+
# @!group pure collection methods
|
47
|
+
def to_c
|
48
|
+
Collection.new(self, klass: @klass, factory: @factory)
|
49
|
+
end
|
50
|
+
|
51
|
+
def new
|
52
|
+
newFrom to_a
|
53
|
+
end
|
54
|
+
|
48
55
|
def newFrom(data)
|
49
56
|
self.class.new(data, klass: @klass, factory: @factory)
|
50
57
|
end
|
@@ -54,14 +61,6 @@ module Eco
|
|
54
61
|
newFrom to_a + data
|
55
62
|
end
|
56
63
|
|
57
|
-
def to_c
|
58
|
-
Collection.new(self, klass: @klass, factory: @factory)
|
59
|
-
end
|
60
|
-
|
61
|
-
def new
|
62
|
-
self.class.new(to_a, klass: @klass, factory: @factory)
|
63
|
-
end
|
64
|
-
|
65
64
|
def length
|
66
65
|
count
|
67
66
|
end
|
@@ -70,7 +69,7 @@ module Eco
|
|
70
69
|
count == 0
|
71
70
|
end
|
72
71
|
|
73
|
-
def each(
|
72
|
+
def each(&block)
|
74
73
|
return to_enum(:each) unless block
|
75
74
|
@items.each(&block)
|
76
75
|
end
|
@@ -93,47 +92,57 @@ module Eco
|
|
93
92
|
def delete!(value)
|
94
93
|
self < @items - into_a(value)
|
95
94
|
end
|
95
|
+
# @!endgroup
|
96
96
|
|
97
|
-
# attr dependant methods
|
98
|
-
def exclude(attr, value, modifier =
|
97
|
+
# @!group `attr` dependant methods
|
98
|
+
def exclude(attr, value, modifier = default_modifier)
|
99
99
|
newFrom @items - self.attr(attr, value, modifier)
|
100
100
|
end
|
101
101
|
|
102
|
-
def remove(attr, value, modifier =
|
102
|
+
def remove(attr, value, modifier = default_modifier)
|
103
103
|
self < exclude(attr, value, modifier)
|
104
104
|
end
|
105
105
|
|
106
|
-
def attr(attr, value = true, modifier =
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
match?(attr_val, value, modifier)
|
113
|
-
}
|
106
|
+
def attr(attr, value = true, modifier = default_modifier)
|
107
|
+
return present(attr, value) if boolean?(value)
|
108
|
+
select do |object|
|
109
|
+
match?(attr_value(object, attr), value, modifier)
|
110
|
+
end.yield_self do |matching|
|
111
|
+
newFrom matching
|
114
112
|
end
|
115
113
|
end
|
116
114
|
|
117
|
-
def attr?(attr, value = true, modifier =
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
115
|
+
def attr?(attr, value = true, modifier = default_modifier)
|
116
|
+
return present(attr, value).length == length if boolean?(value)
|
117
|
+
match?(attrs(attr), value, modifier.new.reverse)
|
118
|
+
end
|
119
|
+
|
120
|
+
def contains(attr, value, modifier = default_modifier)
|
121
|
+
self.attr(attr, value, modifier.new.pattern)
|
125
122
|
end
|
126
123
|
|
127
124
|
def attrs(attr)
|
128
|
-
map { |object|
|
125
|
+
map { |object| attr_value(object, attr) }
|
129
126
|
end
|
130
127
|
|
131
128
|
def unique_attrs(attr)
|
132
129
|
to_h(attr).keys
|
133
130
|
end
|
134
131
|
|
132
|
+
def group_by(attr = nil, &block)
|
133
|
+
return to_h(attr) if attr
|
134
|
+
to_a.group_by(&block) if block
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_h(attr)
|
138
|
+
return {} if !attr
|
139
|
+
to_a.group_by { |object| object.method(attr).call }
|
140
|
+
end
|
141
|
+
# @!endgroup
|
142
|
+
|
143
|
+
# @!group `attr` presence methods
|
135
144
|
def present(attr, flag = true)
|
136
|
-
block = ->(o) {
|
145
|
+
block = ->(o) { attr_value_present?(o, attr) == !!flag }
|
137
146
|
newFrom select(&block)
|
138
147
|
end
|
139
148
|
|
@@ -148,21 +157,7 @@ module Eco
|
|
148
157
|
def present_some?(attr, flag = true)
|
149
158
|
present(attr, flag).length > 0
|
150
159
|
end
|
151
|
-
|
152
|
-
def contains(attr, value, modifier = Language::MatchModifier.new)
|
153
|
-
modifier = modifier.new.pattern
|
154
|
-
self.attr(attr, value, modifier)
|
155
|
-
end
|
156
|
-
|
157
|
-
def group_by(attr = nil, &block)
|
158
|
-
return to_h(attr) if attr
|
159
|
-
to_a.group_by(&block) if block
|
160
|
-
end
|
161
|
-
|
162
|
-
def to_h(attr)
|
163
|
-
return {} if !attr
|
164
|
-
to_a.group_by { |object| object.method(attr).call }
|
165
|
-
end
|
160
|
+
# @!endgroup
|
166
161
|
|
167
162
|
protected
|
168
163
|
|
@@ -171,12 +166,34 @@ module Eco
|
|
171
166
|
end
|
172
167
|
|
173
168
|
def into_a(value)
|
174
|
-
value = [].push(value)
|
169
|
+
value = [].push(value) if value.is_a?(Hash) || !value.is_a?(Enumerable)
|
175
170
|
value.to_a
|
176
171
|
end
|
177
172
|
|
178
173
|
private
|
179
174
|
|
175
|
+
def attr_value(obj, attr)
|
176
|
+
return nil unless obj && attr
|
177
|
+
case
|
178
|
+
when obj.is_a?(Hash)
|
179
|
+
obj[attr]
|
180
|
+
when obj.respond_to?(attr.to_sym)
|
181
|
+
obj.send(attr)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def attr_value_present?(obj, attr)
|
186
|
+
return false unless value = attr_value(obj, attr)
|
187
|
+
case
|
188
|
+
when value.is_a?(Enumerable)
|
189
|
+
value.count > 1
|
190
|
+
when value.is_a?(String)
|
191
|
+
!value.strip.empty?
|
192
|
+
else
|
193
|
+
!!value
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
180
197
|
def match?(*args)
|
181
198
|
@handy.match?(*args)
|
182
199
|
end
|
@@ -187,8 +204,12 @@ module Eco
|
|
187
204
|
end
|
188
205
|
end
|
189
206
|
|
190
|
-
def
|
191
|
-
|
207
|
+
def default_modifier
|
208
|
+
Language::MatchModifier.new
|
209
|
+
end
|
210
|
+
|
211
|
+
def boolean?(value)
|
212
|
+
value == !!value
|
192
213
|
end
|
193
214
|
|
194
215
|
end
|
@@ -1,29 +1,32 @@
|
|
1
1
|
module Eco
|
2
2
|
module Language
|
3
3
|
module Models
|
4
|
-
|
4
|
+
# Basic class to define a parser/serializing framework
|
5
|
+
# @attr_reader attr [String, Symbol] the attribute this parser/serializer is linked to.
|
5
6
|
class ParserSerializer
|
6
|
-
|
7
7
|
attr_reader :attr
|
8
8
|
|
9
9
|
# Parser/seralizer.
|
10
10
|
# @param attr [String, Symbol] name of the parsed/serialized.
|
11
11
|
# @param dependencies [Hash] provisioning of _**default dependencies**_ that will be required when calling back to the
|
12
|
-
#
|
12
|
+
# parsing or serializing functions.
|
13
13
|
def initialize(attr, dependencies: {})
|
14
|
-
@attr
|
14
|
+
@attr = attr
|
15
15
|
@dependencies = dependencies
|
16
|
+
@parser = {}
|
17
|
+
@serializer = {}
|
16
18
|
end
|
17
19
|
|
18
20
|
# Defines the _parser_ of the attribute.
|
19
21
|
# @note
|
20
22
|
# 1. the _block_ should expect one or two parameters.
|
21
23
|
# 2. the final dependencies is a merge of _default dependencies_ with `parse` call dependencies.
|
24
|
+
# @param category [Symbol] a way to classify multiple parsers by category.
|
22
25
|
# @yield [source_data, dependencies] user defined parser that returns the parsed value.
|
23
26
|
# @yieldparam source_data [Any] source data that will be parsed.
|
24
27
|
# @yieldparam dependencies [Hash] hash with the provisioned dependencies.
|
25
|
-
def def_parser(&block)
|
26
|
-
@parser = block
|
28
|
+
def def_parser(category = :default, &block)
|
29
|
+
@parser[category.to_sym] = block
|
27
30
|
self
|
28
31
|
end
|
29
32
|
|
@@ -31,11 +34,12 @@ module Eco
|
|
31
34
|
# @note
|
32
35
|
# 1. the block should expect one or two parameters.
|
33
36
|
# 2. the final dependencies is a merge of _default dependencies_ with `serialize` call dependencies.
|
37
|
+
# @param category [Symbol] a way to classify multiple serializers by category.
|
34
38
|
# @yield [source_data, dependencies] user defined serialiser that returns the serialised value.
|
35
39
|
# @yieldparam source_data [Any] source data that will be serialised.
|
36
40
|
# @yieldparam dependencies [Hash] hash with the provisioned dependencies.
|
37
|
-
def def_serializer(&block)
|
38
|
-
@serializer = block
|
41
|
+
def def_serializer(category = :default, &block)
|
42
|
+
@serializer[category.to_sym] = block
|
39
43
|
self
|
40
44
|
end
|
41
45
|
|
@@ -45,9 +49,9 @@ module Eco
|
|
45
49
|
# @raise [Exception] when there is **no** `parser` defined.
|
46
50
|
# @param source [Any] source data to be parsed.
|
47
51
|
# @param dependencies [Hash] _additional dependencies_ that should be merged to the _default dependencies_.
|
48
|
-
def parse(source, dependencies: {})
|
49
|
-
raise "There is no parser for this attribue '#{attr}'"
|
50
|
-
|
52
|
+
def parse(source, category = :default, dependencies: {})
|
53
|
+
raise "There is no parser of type '#{category}' for this attribue '#{attr}'" unless parser_category?(category)
|
54
|
+
call_block(source, @dependencies.merge(dependencies), attr, &@parser[category.to_sym])
|
51
55
|
end
|
52
56
|
|
53
57
|
# Calls the `serializer` of this attribute by passing `object` and resolved dependencies.
|
@@ -56,13 +60,33 @@ module Eco
|
|
56
60
|
# @raise [Exception] when there is **no** `serializer` defined.
|
57
61
|
# @param object [Any] source data to be serialized.
|
58
62
|
# @param dependencies [Hash] _additional dependencies_ that should be merged to the _default dependencies_.
|
59
|
-
def serialize(object, dependencies: {})
|
60
|
-
raise "There is no serializer for this attribue '#{attr}'"
|
61
|
-
|
63
|
+
def serialize(object, category = :default, dependencies: {})
|
64
|
+
raise "There is no serializer of type '#{category}' for this attribue '#{attr}'" unless serializer_category?(category)
|
65
|
+
call_block(object, @dependencies.merge(dependencies), attr, &@serializer[category.to_sym])
|
62
66
|
end
|
63
67
|
|
64
|
-
|
68
|
+
# Checks if there's a `parser` defined for `category`
|
69
|
+
# @return [Boolean] `true` if the parser is defined, and `false` otherwise
|
70
|
+
def parser_category?(category = :default)
|
71
|
+
@parser.key?(category.to_sym)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Checks if there's a `serializer` defined for `category`
|
75
|
+
# @return [Boolean] `true` if the serializer is defined, and `false` otherwise
|
76
|
+
def serializer_category?(category = :default)
|
77
|
+
@serializer.key?(category.to_sym)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
65
81
|
|
82
|
+
# The methods may expect less parameters from some type of parsers.
|
83
|
+
# Here, we ensure they are called with the expected number of parameters.
|
84
|
+
def call_block(*args, &block)
|
85
|
+
params = block.parameters.zip(args).map(&:last)
|
86
|
+
yield(*params)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
66
90
|
end
|
67
91
|
end
|
68
92
|
end
|