hashcraft 1.0.0.pre.alpha.5 → 1.0.0.pre.alpha.6
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/.gitignore +1 -2
- data/lib/hashcraft.rb +1 -4
- data/lib/hashcraft/base.rb +2 -15
- data/lib/hashcraft/dsl.rb +23 -9
- data/lib/hashcraft/generic/dictionary.rb +1 -5
- data/lib/hashcraft/generic/registry.rb +1 -1
- data/lib/hashcraft/mutator_registry.rb +3 -3
- data/lib/hashcraft/mutators/always_false.rb +1 -1
- data/lib/hashcraft/mutators/always_true.rb +1 -1
- data/lib/hashcraft/mutators/array.rb +1 -1
- data/lib/hashcraft/mutators/flat_array.rb +1 -1
- data/lib/hashcraft/mutators/hash.rb +1 -1
- data/lib/hashcraft/mutators/property.rb +1 -1
- data/lib/hashcraft/option.rb +12 -5
- data/lib/hashcraft/transformer_registry.rb +3 -3
- data/lib/hashcraft/transformers/camel_case.rb +1 -1
- data/lib/hashcraft/transformers/pascal_case.rb +1 -1
- data/lib/hashcraft/transformers/pass_thru.rb +1 -1
- data/lib/hashcraft/version.rb +1 -1
- metadata +1 -2
- data/lib/hashcraft/core_ext/hash.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c70ff2e1bf5cecc91ae33eba7b1fb5810371ab3f67a4f077e02c0dc8a3b6fac8
|
4
|
+
data.tar.gz: b116b485b82e3cacc55e7a217d3682a06334a970c105eef95db01f054bf44655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a03980f411dd97dd6744780fa01a74891f618703faaa3b06c24cd2f088ab387a4127ab17d9c9b0f02c7c746fd0701ee66743d4debee5e4c29f9c8704d03f2cca
|
7
|
+
data.tar.gz: e90a7ea856b01fd8298e30a2eef2c1ad81d0337c819792a0df8108145419caa1fe19502502c0a3df17f1e24b792c435b4e7983030dc61cb2d4f310cbb7a639e3
|
data/.gitignore
CHANGED
data/lib/hashcraft.rb
CHANGED
@@ -10,11 +10,8 @@
|
|
10
10
|
require 'forwardable'
|
11
11
|
require 'singleton'
|
12
12
|
|
13
|
-
# Monkey-patching core libraries
|
14
|
-
require_relative 'hashcraft/core_ext/hash'
|
15
|
-
Hash.include Hashcraft::CoreExt::Hash
|
16
|
-
|
17
13
|
# General tooling
|
18
14
|
require_relative 'hashcraft/generic'
|
19
15
|
|
16
|
+
# Main Entrypoint(s)
|
20
17
|
require_relative 'hashcraft/base'
|
data/lib/hashcraft/base.rb
CHANGED
@@ -16,7 +16,6 @@ module Hashcraft
|
|
16
16
|
extend Forwardable
|
17
17
|
|
18
18
|
def_delegators :'self.class',
|
19
|
-
:option?,
|
20
19
|
:option_set,
|
21
20
|
:find_option,
|
22
21
|
:key_transformer_to_use,
|
@@ -37,6 +36,8 @@ module Hashcraft
|
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
39
|
+
# Main compilation method. Once an object is hydrated, you can call this method to get the
|
40
|
+
# materialized hash.
|
40
41
|
def to_h
|
41
42
|
data.each_with_object({}) do |(key, value), memo|
|
42
43
|
method = value.is_a?(Array) ? :evaluate_values! : :evaluate_value!
|
@@ -57,20 +58,6 @@ module Hashcraft
|
|
57
58
|
(opts || {}).each { |k, v| send(k, v) }
|
58
59
|
end
|
59
60
|
|
60
|
-
def respond_to_missing?(method_name, include_private = false)
|
61
|
-
option?(method_name) || super
|
62
|
-
end
|
63
|
-
|
64
|
-
def method_missing(method_name, *arguments, &block)
|
65
|
-
if option?(method_name)
|
66
|
-
option = find_option(method_name)
|
67
|
-
|
68
|
-
value!(option, arguments.first, &block)
|
69
|
-
else
|
70
|
-
super
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
61
|
def evaluate_values!(data, key, values)
|
75
62
|
data[key] ||= []
|
76
63
|
|
data/lib/hashcraft/dsl.rb
CHANGED
@@ -18,15 +18,21 @@ module Hashcraft
|
|
18
18
|
attr_reader :local_key_transformer,
|
19
19
|
:local_value_transformer
|
20
20
|
|
21
|
+
# DSL Method used to declare what the sub-class should use as a transformer for all keys.
|
22
|
+
# It will follow the typical inheritance chain and find the closest
|
23
|
+
# transformer to use (child-first).
|
21
24
|
def key_transformer(name)
|
22
25
|
tap { @local_key_transformer = TransformerRegistry.resolve(name) }
|
23
26
|
end
|
24
27
|
|
28
|
+
# DSL Method used to declare what the sub-class should use as a transformer for all values.
|
29
|
+
# It will follow the typical inheritance chain and find the closest
|
30
|
+
# transformer to use (child-first).
|
25
31
|
def value_transformer(name)
|
26
32
|
tap { @local_value_transformer = TransformerRegistry.resolve(name) }
|
27
33
|
end
|
28
34
|
|
29
|
-
def key_transformer_to_use
|
35
|
+
def key_transformer_to_use # :nodoc:
|
30
36
|
return @key_transformer_to_use if @key_transformer_to_use
|
31
37
|
|
32
38
|
@closest_key_transformer =
|
@@ -35,7 +41,7 @@ module Hashcraft
|
|
35
41
|
&.local_key_transformer || Transformers::PassThru.instance
|
36
42
|
end
|
37
43
|
|
38
|
-
def value_transformer_to_use
|
44
|
+
def value_transformer_to_use # :nodoc:
|
39
45
|
return @value_transformer_to_use if @value_transformer_to_use
|
40
46
|
|
41
47
|
@closest_value_transformer =
|
@@ -44,14 +50,12 @@ module Hashcraft
|
|
44
50
|
&.local_value_transformer || Transformers::PassThru.instance
|
45
51
|
end
|
46
52
|
|
47
|
-
def
|
48
|
-
option_set.exist?(name)
|
49
|
-
end
|
50
|
-
|
51
|
-
def find_option(name)
|
53
|
+
def find_option(name) # :nodoc:
|
52
54
|
option_set.find(name)
|
53
55
|
end
|
54
56
|
|
57
|
+
# The main class-level DSL method consumed by sub-classes. This is the entry-point for the
|
58
|
+
# declaration of available options.
|
55
59
|
def option(*args)
|
56
60
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
57
61
|
|
@@ -59,12 +63,22 @@ module Hashcraft
|
|
59
63
|
option = Option.new(key, opts)
|
60
64
|
|
61
65
|
local_option_set.add(option)
|
66
|
+
|
67
|
+
method_name = option.name
|
68
|
+
|
69
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
70
|
+
def #{method_name}(opts = {}, &block)
|
71
|
+
option = find_option('#{method_name}')
|
72
|
+
|
73
|
+
value!(option, opts, &block)
|
74
|
+
end
|
75
|
+
RUBY
|
62
76
|
end
|
63
77
|
|
64
78
|
self
|
65
79
|
end
|
66
80
|
|
67
|
-
def option_set
|
81
|
+
def option_set # :nodoc:
|
68
82
|
@option_set ||=
|
69
83
|
ancestors
|
70
84
|
.reverse
|
@@ -72,7 +86,7 @@ module Hashcraft
|
|
72
86
|
.each_with_object(Generic::Dictionary.new) { |a, memo| memo.merge!(a.local_option_set) }
|
73
87
|
end
|
74
88
|
|
75
|
-
def local_option_set
|
89
|
+
def local_option_set # :nodoc:
|
76
90
|
@local_option_set ||= Generic::Dictionary.new(key: :name)
|
77
91
|
end
|
78
92
|
end
|
@@ -8,7 +8,7 @@
|
|
8
8
|
#
|
9
9
|
|
10
10
|
module Hashcraft
|
11
|
-
module Generic
|
11
|
+
module Generic # :nodoc: all
|
12
12
|
# Dictionary structure defining how we want to organize objects. Basically a type-insensitive
|
13
13
|
# hash where each key is the object's value for the specified key.
|
14
14
|
# All keys are #to_s evaluated in order to achieve the type-insensitivity.
|
@@ -34,10 +34,6 @@ module Hashcraft
|
|
34
34
|
values.each(&block)
|
35
35
|
end
|
36
36
|
|
37
|
-
def exist?(key)
|
38
|
-
!find(key).nil?
|
39
|
-
end
|
40
|
-
|
41
37
|
def find(key)
|
42
38
|
@map[key.to_s]
|
43
39
|
end
|
@@ -16,16 +16,16 @@ require_relative 'mutators/property'
|
|
16
16
|
|
17
17
|
module Hashcraft
|
18
18
|
# Singleton that knows how to register and retrieve mutator instances.
|
19
|
-
class MutatorRegistry < Generic::Registry
|
19
|
+
class MutatorRegistry < Generic::Registry # :nodoc:
|
20
20
|
def initialize
|
21
21
|
super(
|
22
|
+
'' => Mutators::Property.instance,
|
22
23
|
'always_false' => Mutators::AlwaysFalse.instance,
|
23
24
|
'always_true' => Mutators::AlwaysTrue.instance,
|
24
25
|
'array' => Mutators::Array.instance,
|
25
26
|
'flat_array' => Mutators::FlatArray.instance,
|
26
27
|
'hash' => Mutators::Hash.instance,
|
27
|
-
'property' => Mutators::Property.instance
|
28
|
-
'' => Mutators::Property.instance
|
28
|
+
'property' => Mutators::Property.instance
|
29
29
|
)
|
30
30
|
end
|
31
31
|
end
|
data/lib/hashcraft/option.rb
CHANGED
@@ -21,13 +21,13 @@ module Hashcraft
|
|
21
21
|
|
22
22
|
alias eager? eager
|
23
23
|
|
24
|
-
def initialize(name, opts = {})
|
24
|
+
def initialize(name, opts = {}) # :nodoc:
|
25
25
|
raise ArgumentError, 'name is required' if name.to_s.empty?
|
26
26
|
|
27
27
|
@craft = opts[:craft]
|
28
28
|
@default = opts[:default]
|
29
29
|
@eager = opts[:eager] || false
|
30
|
-
@internal_meta = (opts[:meta] || {})
|
30
|
+
@internal_meta = symbolize_keys(opts[:meta] || {})
|
31
31
|
@key = opts[:key].to_s
|
32
32
|
@mutator = MutatorRegistry.resolve(opts[:mutator])
|
33
33
|
@name = name.to_s
|
@@ -35,24 +35,31 @@ module Hashcraft
|
|
35
35
|
freeze
|
36
36
|
end
|
37
37
|
|
38
|
-
def value!(data, key, value)
|
38
|
+
def value!(data, key, value) # :nodoc:
|
39
39
|
mutator.value!(data, key, value)
|
40
40
|
end
|
41
41
|
|
42
|
+
# Options are sent into transformers as arguments. Leverage the meta key for an option
|
43
|
+
# to store any additional data that you may need in transformers. This method provides a
|
44
|
+
# quick message-based entry point into inspecting the meta key's value.
|
42
45
|
def meta(key)
|
43
46
|
internal_meta[key.to_s.to_sym]
|
44
47
|
end
|
45
48
|
|
46
|
-
def hash_key
|
49
|
+
def hash_key # :nodoc:
|
47
50
|
key.empty? ? name : key
|
48
51
|
end
|
49
52
|
|
50
|
-
def craft_value(value, &block)
|
53
|
+
def craft_value(value, &block) # :nodoc:
|
51
54
|
craft ? craft.new(value, &block) : value
|
52
55
|
end
|
53
56
|
|
54
57
|
private
|
55
58
|
|
56
59
|
attr_reader :internal_meta
|
60
|
+
|
61
|
+
def symbolize_keys(hash)
|
62
|
+
hash.map { |k, v| [k.to_sym, v] }.to_h
|
63
|
+
end
|
57
64
|
end
|
58
65
|
end
|
@@ -13,13 +13,13 @@ require_relative 'transformers/pass_thru'
|
|
13
13
|
|
14
14
|
module Hashcraft
|
15
15
|
# Singleton that knows how to register and retrieve transformer instances.
|
16
|
-
class TransformerRegistry < Generic::Registry
|
16
|
+
class TransformerRegistry < Generic::Registry # :nodoc:
|
17
17
|
def initialize
|
18
18
|
super(
|
19
|
+
'' => Transformers::PassThru.instance,
|
19
20
|
'camel_case' => Transformers::CamelCase.instance,
|
20
21
|
'pascal_case' => Transformers::PascalCase.instance,
|
21
|
-
'pass_thru' => Transformers::PassThru.instance
|
22
|
-
'' => Transformers::PassThru.instance
|
22
|
+
'pass_thru' => Transformers::PassThru.instance
|
23
23
|
)
|
24
24
|
end
|
25
25
|
end
|
data/lib/hashcraft/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
@@ -132,7 +132,6 @@ files:
|
|
132
132
|
- hashcraft.gemspec
|
133
133
|
- lib/hashcraft.rb
|
134
134
|
- lib/hashcraft/base.rb
|
135
|
-
- lib/hashcraft/core_ext/hash.rb
|
136
135
|
- lib/hashcraft/dsl.rb
|
137
136
|
- lib/hashcraft/generic.rb
|
138
137
|
- lib/hashcraft/generic/dictionary.rb
|
@@ -1,21 +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
|
-
module CoreExt
|
12
|
-
# Monkey-patches for the core Hash class. These will be manually mixed in separately.
|
13
|
-
module Hash
|
14
|
-
unless method_defined?(:symbolize_keys)
|
15
|
-
def symbolize_keys
|
16
|
-
map { |k, v| [k.to_sym, v] }.to_h
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|