hashcraft 1.0.0.pre.alpha.2 → 1.0.0.pre.alpha.3
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/lib/hashcraft.rb +0 -2
- data/lib/hashcraft/base.rb +39 -10
- data/lib/hashcraft/dsl.rb +17 -0
- data/lib/hashcraft/option.rb +29 -11
- data/lib/hashcraft/version.rb +1 -1
- metadata +2 -3
- data/lib/hashcraft/compiler.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5eeb66db8e62e9998006101e746cf23be8e66da88a98b3292b3f769b89fb5bd9
|
4
|
+
data.tar.gz: dba52c0e835c9c09fb82e5fa963d45c57a8988dcde962eb8bb5e6e3feb0e3a9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d493d7190833e14ed7c14f3deaeec7a86ad1d779cdd93d22141d80195986a0c18382fa1011e4cce2fd872ca2ea1c00aca4797aafdc70193b9405ccfd0c0af82
|
7
|
+
data.tar.gz: aae0ba2e2b5dd0b7bd55514276d823337dcfe7e0f5a17fe149cfbc521117b3706a31c9056516c2fd0c1d7f495f2d48859ac4b77f9ee66d94a01155ad4d417768
|
data/lib/hashcraft.rb
CHANGED
data/lib/hashcraft/base.rb
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
require_relative 'compiler'
|
11
10
|
require_relative 'dsl'
|
12
11
|
|
13
12
|
module Hashcraft
|
@@ -19,7 +18,9 @@ module Hashcraft
|
|
19
18
|
def_delegators :'self.class',
|
20
19
|
:option?,
|
21
20
|
:option_set,
|
22
|
-
:find_option
|
21
|
+
:find_option,
|
22
|
+
:key_transformer_object,
|
23
|
+
:value_transformer_object
|
23
24
|
|
24
25
|
def initialize(opts = {}, &block)
|
25
26
|
@data = make_default_data
|
@@ -35,12 +36,12 @@ module Hashcraft
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
def to_h
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
def to_h
|
40
|
+
data.each_with_object({}) do |(key, value), memo|
|
41
|
+
method = value.is_a?(Array) ? :evaluate_values! : :evaluate_value!
|
42
|
+
|
43
|
+
send(method, memo, key, value)
|
44
|
+
end
|
44
45
|
end
|
45
46
|
|
46
47
|
private
|
@@ -48,7 +49,13 @@ module Hashcraft
|
|
48
49
|
attr_reader :data
|
49
50
|
|
50
51
|
def make_default_data
|
51
|
-
option_set.values.each_with_object({})
|
52
|
+
option_set.values.each_with_object({}) do |o, memo|
|
53
|
+
o.default!(
|
54
|
+
memo,
|
55
|
+
key_transformer_object,
|
56
|
+
value_transformer_object
|
57
|
+
)
|
58
|
+
end
|
52
59
|
end
|
53
60
|
|
54
61
|
def load_opts(opts)
|
@@ -61,10 +68,32 @@ module Hashcraft
|
|
61
68
|
|
62
69
|
def method_missing(method_name, *arguments, &block)
|
63
70
|
if option?(method_name)
|
64
|
-
find_option(method_name).value!(
|
71
|
+
find_option(method_name).value!(
|
72
|
+
data,
|
73
|
+
arguments.first,
|
74
|
+
key_transformer_object,
|
75
|
+
value_transformer_object,
|
76
|
+
&block
|
77
|
+
)
|
65
78
|
else
|
66
79
|
super
|
67
80
|
end
|
68
81
|
end
|
82
|
+
|
83
|
+
def evaluate_values!(data, key, values)
|
84
|
+
data[key] ||= []
|
85
|
+
|
86
|
+
values.each do |value|
|
87
|
+
data[key] << (value.is_a?(Hashcraft::Base) ? value.to_h : value)
|
88
|
+
end
|
89
|
+
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def evaluate_value!(data, key, value)
|
94
|
+
data[key] = (value.is_a?(Hashcraft::Base) ? value.to_h : value)
|
95
|
+
|
96
|
+
self
|
97
|
+
end
|
69
98
|
end
|
70
99
|
end
|
data/lib/hashcraft/dsl.rb
CHANGED
@@ -8,12 +8,21 @@
|
|
8
8
|
#
|
9
9
|
|
10
10
|
require_relative 'option'
|
11
|
+
require_relative 'transformer_registry'
|
11
12
|
|
12
13
|
module Hashcraft
|
13
14
|
# The class API used to define options for a craftable class. Each class stores its own
|
14
15
|
# OptionSet instance along with materializing one for its
|
15
16
|
# inheritance chain (child has precedence.)
|
16
17
|
module Dsl
|
18
|
+
def key_transformer(name)
|
19
|
+
tap { @key_transformer_object = TransformerRegistry.resolve(name) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def value_transformer(name)
|
23
|
+
tap { @value_transformer_object = TransformerRegistry.resolve(name) }
|
24
|
+
end
|
25
|
+
|
17
26
|
def option?(name)
|
18
27
|
option_set.exist?(name)
|
19
28
|
end
|
@@ -45,5 +54,13 @@ module Hashcraft
|
|
45
54
|
def local_option_set
|
46
55
|
@local_option_set ||= Generic::Dictionary.new(key: :name)
|
47
56
|
end
|
57
|
+
|
58
|
+
def key_transformer_object
|
59
|
+
@key_transformer_object || Transformers::PassThru.instance
|
60
|
+
end
|
61
|
+
|
62
|
+
def value_transformer_object
|
63
|
+
@value_transformer_object || Transformers::PassThru.instance
|
64
|
+
end
|
48
65
|
end
|
49
66
|
end
|
data/lib/hashcraft/option.rb
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
+
require_relative 'mutator_registry'
|
11
|
+
|
10
12
|
module Hashcraft
|
11
13
|
# Defines a method and corresponding attribute for a craftable class.
|
12
14
|
class Option
|
@@ -20,13 +22,13 @@ module Hashcraft
|
|
20
22
|
def initialize(name, opts = {})
|
21
23
|
raise ArgumentError, 'name is required' if name.to_s.empty?
|
22
24
|
|
23
|
-
@craft
|
24
|
-
@default
|
25
|
-
@eager
|
26
|
-
@internal_meta
|
27
|
-
@key
|
28
|
-
@mutator
|
29
|
-
@name
|
25
|
+
@craft = opts[:craft]
|
26
|
+
@default = opts[:default]
|
27
|
+
@eager = opts[:eager] || false
|
28
|
+
@internal_meta = (opts[:meta] || {}).symbolize_keys
|
29
|
+
@key = opts[:key].to_s
|
30
|
+
@mutator = MutatorRegistry.resolve(opts[:mutator])
|
31
|
+
@name = name.to_s
|
30
32
|
|
31
33
|
freeze
|
32
34
|
end
|
@@ -35,18 +37,30 @@ module Hashcraft
|
|
35
37
|
internal_meta[key.to_s.to_sym]
|
36
38
|
end
|
37
39
|
|
38
|
-
def default!(data)
|
40
|
+
def default!(data, key_transformer, value_transformer)
|
39
41
|
return self unless eager
|
40
42
|
|
41
|
-
|
43
|
+
final_key = hash_key(key_transformer)
|
44
|
+
value = value_transformer.transform(default.dup, self)
|
45
|
+
|
46
|
+
data[final_key] = value
|
42
47
|
|
43
48
|
self
|
44
49
|
end
|
45
50
|
|
46
|
-
def value!(
|
51
|
+
def value!(
|
52
|
+
data,
|
53
|
+
value,
|
54
|
+
key_transformer,
|
55
|
+
value_transformer,
|
56
|
+
&block
|
57
|
+
)
|
47
58
|
value = craft_value(value, &block)
|
59
|
+
value = value_transformer.transform(value, self)
|
60
|
+
|
61
|
+
final_key = hash_key(key_transformer)
|
48
62
|
|
49
|
-
mutator.value!(data,
|
63
|
+
mutator.value!(data, final_key, value)
|
50
64
|
|
51
65
|
self
|
52
66
|
end
|
@@ -55,6 +69,10 @@ module Hashcraft
|
|
55
69
|
|
56
70
|
attr_reader :internal_meta
|
57
71
|
|
72
|
+
def hash_key(key_transformer)
|
73
|
+
key_transformer.transform(key.empty? ? name : key, self)
|
74
|
+
end
|
75
|
+
|
58
76
|
def craft_value(value, &block)
|
59
77
|
craft ? craft.new(value, &block) : value
|
60
78
|
end
|
data/lib/hashcraft/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashcraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.alpha.
|
4
|
+
version: 1.0.0.pre.alpha.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: guard-rspec
|
@@ -132,7 +132,6 @@ files:
|
|
132
132
|
- hashcraft.gemspec
|
133
133
|
- lib/hashcraft.rb
|
134
134
|
- lib/hashcraft/base.rb
|
135
|
-
- lib/hashcraft/compiler.rb
|
136
135
|
- lib/hashcraft/core_ext/hash.rb
|
137
136
|
- lib/hashcraft/dsl.rb
|
138
137
|
- lib/hashcraft/generic.rb
|
data/lib/hashcraft/compiler.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
-
#
|
6
|
-
# This source code is licensed under the MIT license found in the
|
7
|
-
# LICENSE file in the root directory of this source tree.
|
8
|
-
#
|
9
|
-
|
10
|
-
module Hashcraft
|
11
|
-
# This class understands how to traverse an option chain and output a hash.
|
12
|
-
class Compiler
|
13
|
-
attr_reader :key_transformer, :option_set, :value_transformer
|
14
|
-
|
15
|
-
def initialize(option_set, key_transformer: nil, value_transformer: nil)
|
16
|
-
raise ArgumentError, 'option_set is required' unless option_set
|
17
|
-
|
18
|
-
@option_set = option_set
|
19
|
-
@key_transformer = TransformerRegistry.resolve(key_transformer)
|
20
|
-
@value_transformer = TransformerRegistry.resolve(value_transformer)
|
21
|
-
|
22
|
-
freeze
|
23
|
-
end
|
24
|
-
|
25
|
-
def evaluate!(data)
|
26
|
-
data.each_with_object({}) do |(key, value), memo|
|
27
|
-
option = option_set.find(key)
|
28
|
-
|
29
|
-
evaluate_single!(memo, option, value)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
attr_reader :data
|
36
|
-
|
37
|
-
def evaluate_single!(data, option, value)
|
38
|
-
key = option.key.empty? ? option.name : option.key
|
39
|
-
transformed_key = key_transformer.transform(key, option)
|
40
|
-
|
41
|
-
method = value.is_a?(Array) ? :evaluate_values! : :evaluate_value!
|
42
|
-
|
43
|
-
send(method, option, data, transformed_key, value)
|
44
|
-
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
def evaluate_values!(option, data, key, values)
|
49
|
-
data[key] ||= []
|
50
|
-
|
51
|
-
values.each do |value|
|
52
|
-
data[key] <<
|
53
|
-
if value.is_a?(Hashcraft::Base)
|
54
|
-
value.to_h(
|
55
|
-
key_transformer: key_transformer,
|
56
|
-
value_transformer: value_transformer
|
57
|
-
)
|
58
|
-
else
|
59
|
-
value_transformer.transform(value, option)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
self
|
64
|
-
end
|
65
|
-
|
66
|
-
def evaluate_value!(option, data, key, value)
|
67
|
-
data[key] =
|
68
|
-
if value.is_a?(Hashcraft::Base)
|
69
|
-
value.to_h(
|
70
|
-
key_transformer: key_transformer,
|
71
|
-
value_transformer: value_transformer
|
72
|
-
)
|
73
|
-
else
|
74
|
-
value_transformer.transform(value, option)
|
75
|
-
end
|
76
|
-
|
77
|
-
self
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|