hashcraft 1.0.0.pre.alpha.5 → 1.0.0.pre.alpha.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|