smart_kv 0.1.3 → 0.1.4
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/.coveralls.yml +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +18 -0
- data/README.md +74 -13
- data/lib/smart_kv.rb +0 -6
- data/lib/smart_kv/register.rb +11 -1
- data/lib/smart_kv/version.rb +1 -1
- data/smart_kv.gemspec +1 -1
- metadata +5 -5
- data/lib/smart_kv/macro.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 420ce0e7d38260c55c3727e37875a5d0874c500ec3c47c402b309a3d026c77ab
|
4
|
+
data.tar.gz: 58c5c54dad2de77d66d64253672a842be8fab34fa744c3d287dfbac34d68acf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c6a325bdee6c9ce5e70e0384afc79f5d754798077667294f0d672d1ea947438fa1860f1e4fe6f1b5fcb68b7a374a2d135744cc78d4eed1b730b25773ba6a17f
|
7
|
+
data.tar.gz: 70c77c085f843d4f8b8d2e533e7bbe180c4cb9da7f38cc5b4066d891775a22e84e88524cf390ba22c9536da23c1da6148a0c76058996106f70bcfcc3c6aa1ded
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: 2GrR1SPa8lXAm5kYn2fqp4N7pJGbvW8rO
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -3,7 +3,15 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
byebug (10.0.2)
|
5
5
|
coderay (1.1.2)
|
6
|
+
coveralls (0.8.22)
|
7
|
+
json (>= 1.8, < 3)
|
8
|
+
simplecov (~> 0.16.1)
|
9
|
+
term-ansicolor (~> 1.3)
|
10
|
+
thor (~> 0.19.4)
|
11
|
+
tins (~> 1.6)
|
6
12
|
diff-lcs (1.3)
|
13
|
+
docile (1.3.1)
|
14
|
+
json (2.1.0)
|
7
15
|
method_source (0.9.2)
|
8
16
|
pry (0.12.2)
|
9
17
|
coderay (~> 1.1.0)
|
@@ -25,12 +33,22 @@ GEM
|
|
25
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
26
34
|
rspec-support (~> 3.8.0)
|
27
35
|
rspec-support (3.8.0)
|
36
|
+
simplecov (0.16.1)
|
37
|
+
docile (~> 1.1)
|
38
|
+
json (>= 1.8, < 3)
|
39
|
+
simplecov-html (~> 0.10.0)
|
40
|
+
simplecov-html (0.10.2)
|
41
|
+
term-ansicolor (1.7.0)
|
42
|
+
tins (~> 1.0)
|
43
|
+
thor (0.19.4)
|
44
|
+
tins (1.20.2)
|
28
45
|
|
29
46
|
PLATFORMS
|
30
47
|
ruby
|
31
48
|
|
32
49
|
DEPENDENCIES
|
33
50
|
bundler (~> 1.17)
|
51
|
+
coveralls
|
34
52
|
pry (~> 0.12)
|
35
53
|
pry-byebug (~> 3.6)
|
36
54
|
rake (~> 10.0)
|
data/README.md
CHANGED
@@ -1,25 +1,64 @@
|
|
1
1
|
# SmartKv
|
2
2
|
|
3
3
|
[](https://travis-ci.org/styd/smart_kv)
|
4
|
+
[](https://coveralls.io/github/styd/smart_kv?branch=master)
|
5
|
+
[](https://rubygems.org/gems/smart_kv)
|
4
6
|
|
5
|
-
Best practice of writing configurations by strictly allowing and requiring keys.
|
7
|
+
Best practice of writing options or configurations by strictly allowing and requiring keys.
|
6
8
|
|
7
|
-
It doesn't have to be
|
9
|
+
It doesn't have to be options or configurations.
|
8
10
|
You can use it for strict request body or other use cases too.
|
9
11
|
|
10
|
-
##
|
12
|
+
## Background
|
11
13
|
|
12
|
-
|
14
|
+
Have you ever used ruby options like this:
|
13
15
|
|
14
16
|
```ruby
|
15
|
-
|
17
|
+
# this example is for rails
|
18
|
+
d = DateTime.now
|
19
|
+
e = d.change(hour: 1, minute: 5)
|
16
20
|
```
|
17
21
|
|
18
|
-
|
22
|
+
and then move on with your life.. until you realize that the code doesn't behave as you expected it to behave.
|
23
|
+
But why? Everything looks fine, right? Yes, it does look fine.. but it's not fine.
|
19
24
|
|
20
|
-
|
25
|
+
So, what's the problem?
|
26
|
+
The problem was the option key `:minute` was not recognized.
|
27
|
+
Eh? :confused:
|
28
|
+
Why didn't it tell me if it was not recognized?
|
29
|
+
|
30
|
+
I wish that too.
|
31
|
+
But `Hash` has a default value of `nil` if key is not found (same thing applies to `OpenStruct`) - so, it will not raise error -
|
32
|
+
and most developers won't bother checking each options' key made by the users of the library or method.
|
21
33
|
|
22
|
-
|
34
|
+
If only the source of the `DateTime#change` method starts like this:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# this class can be defined on its own file
|
38
|
+
class ChangeOptions < SmartKv
|
39
|
+
optional :nsec, :usec, :year, :month, :day, :hour, :min, :sec, :offset, :start
|
40
|
+
end
|
41
|
+
|
42
|
+
class DateTime
|
43
|
+
...
|
44
|
+
def change(options)
|
45
|
+
options = ChangeOptions.new(options)
|
46
|
+
...
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
So, when you do this `d.change(hour: 1, minute: 5)`, it will yell:
|
52
|
+
|
53
|
+
```
|
54
|
+
NotImplementedError: unrecognized key(s): `:minute' in ChangeOptions
|
55
|
+
```
|
56
|
+
|
57
|
+
Well, this is better. But, how do you know all the right options?
|
58
|
+
Type: `ChangeOptions.optional_keys` and `ChangeOptions.required_keys`.
|
59
|
+
|
60
|
+
|
61
|
+
## More Usage Example
|
23
62
|
|
24
63
|
```ruby
|
25
64
|
class Config < SmartKv
|
@@ -31,7 +70,9 @@ Config.new({some_key: "val"})
|
|
31
70
|
```
|
32
71
|
|
33
72
|
This will complain that you're not using the `:second key`.
|
34
|
-
|
73
|
+
If you add another key that is not recognized, it will complain too.
|
74
|
+
If there is a key that you don't always use but want it to be recognized, mark it as `optional`.
|
75
|
+
|
35
76
|
|
36
77
|
### Inheritable
|
37
78
|
|
@@ -45,6 +86,7 @@ ChildConfig.new({first_key: "val", second_key: "val 2"})
|
|
45
86
|
|
46
87
|
This will also complain that you're not using the `:some_key`.
|
47
88
|
|
89
|
+
|
48
90
|
### Directly callable
|
49
91
|
|
50
92
|
Whatever given as input is callable directly.
|
@@ -57,6 +99,7 @@ c2 = Config.new(OpenStruct.new({some_key: "val", second_key: "val 2"}))
|
|
57
99
|
c2.second_key
|
58
100
|
```
|
59
101
|
|
102
|
+
|
60
103
|
### Override callable object
|
61
104
|
|
62
105
|
You can change the callable object to any class that accepts hash as input of its new class method.
|
@@ -71,9 +114,10 @@ c = Convertable.new({abcd: 123})
|
|
71
114
|
c.abcd #=> 123
|
72
115
|
```
|
73
116
|
|
74
|
-
### Not using it for config
|
75
117
|
|
76
|
-
|
118
|
+
### Not using it for options or configs?
|
119
|
+
|
120
|
+
You can choose not to use it for options or configs. Maybe for strict request body keys?
|
77
121
|
|
78
122
|
```ruby
|
79
123
|
class PostBody < SmartKv
|
@@ -84,22 +128,39 @@ end
|
|
84
128
|
request.set_form_data(PostBody.new({app_key: "abc", secret_key: "def"}))
|
85
129
|
```
|
86
130
|
|
131
|
+
|
132
|
+
## Installation
|
133
|
+
|
134
|
+
Add this line to your application's Gemfile:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
gem 'smart_kv'
|
138
|
+
```
|
139
|
+
|
140
|
+
And then execute:
|
141
|
+
|
142
|
+
$ bundle
|
143
|
+
|
144
|
+
|
87
145
|
## Coming Soon
|
88
146
|
|
89
|
-
- [ ] Make it serializable
|
90
147
|
- [X] Convertable from hash (as input) to OpenStruct (the resulting object) or another object and vice versa
|
91
|
-
- [ ]
|
148
|
+
- [ ] Suggests corrections for unrecognized keys using DidYouMean (and maybe change the spell checking threshold?)
|
92
149
|
- [ ] Support nested/deep key value object as input
|
93
150
|
- [ ] Make some nested keys from the same parent key required and some others optional
|
151
|
+
- [ ] Accept config file (e.g. `json`, `yaml`, etc.) or file path as input
|
152
|
+
|
94
153
|
|
95
154
|
## Contributing
|
96
155
|
|
97
156
|
Bug reports and pull requests are welcome on GitHub at https://github.com/styd/smart_kv. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
98
157
|
|
158
|
+
|
99
159
|
## License
|
100
160
|
|
101
161
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
102
162
|
|
163
|
+
|
103
164
|
## Code of Conduct
|
104
165
|
|
105
166
|
Everyone interacting in the SmartKv project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/styd/smart_kv/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/smart_kv.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
require "smart_kv/version"
|
2
2
|
require "smart_kv/register"
|
3
|
-
require "smart_kv/macro"
|
4
3
|
|
5
4
|
SmartKvInitializationError = Class.new(StandardError)
|
6
5
|
|
7
6
|
class SmartKv
|
8
7
|
extend Register
|
9
|
-
extend Macro
|
10
8
|
|
11
9
|
attr_reader :object_class
|
12
10
|
|
@@ -16,10 +14,6 @@ class SmartKv
|
|
16
14
|
@object_class = object_class || kv.class
|
17
15
|
@kv = kv.dup
|
18
16
|
|
19
|
-
if @object_class.respond_to?(:members) && @object_class.members != @kv.to_h.keys
|
20
|
-
raise ArgumentError, "#{ @object_class } struct size differs"
|
21
|
-
end
|
22
|
-
|
23
17
|
hash = kv.to_h.dup
|
24
18
|
missing_keys = required_keys - hash.keys
|
25
19
|
unless missing_keys.empty?
|
data/lib/smart_kv/register.rb
CHANGED
@@ -2,6 +2,8 @@ module SmartKv::Register
|
|
2
2
|
def required(*args)
|
3
3
|
@required ||= superclass == SmartKv ? Set.new : superclass.required_keys.dup
|
4
4
|
@required += args
|
5
|
+
@optional -= @required if @optional
|
6
|
+
@required
|
5
7
|
end
|
6
8
|
|
7
9
|
def required_keys
|
@@ -11,7 +13,7 @@ module SmartKv::Register
|
|
11
13
|
def optional(*args)
|
12
14
|
@optional ||= superclass == SmartKv ? Set.new : superclass.optional_keys.dup
|
13
15
|
@optional += args
|
14
|
-
@required -= @optional
|
16
|
+
@required -= @optional if @required
|
15
17
|
@optional
|
16
18
|
end
|
17
19
|
|
@@ -22,4 +24,12 @@ module SmartKv::Register
|
|
22
24
|
def new(*args)
|
23
25
|
super(@required.to_a, @optional.to_a, @callable_as, *args)
|
24
26
|
end
|
27
|
+
|
28
|
+
def callable_as(klass)
|
29
|
+
@callable_as = superclass == SmartKv ? klass : superclass.callable_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def callable_class
|
33
|
+
@callable_as
|
34
|
+
end
|
25
35
|
end
|
data/lib/smart_kv/version.rb
CHANGED
data/smart_kv.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["a.styd@yahoo.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Smart checks for your key value objects.}
|
13
|
-
spec.description = %q{Best practice of writing configurations by strictly allowing and requiring keys.}
|
13
|
+
spec.description = %q{Best practice of writing options or configurations by strictly allowing and requiring keys.}
|
14
14
|
spec.homepage = "https://github.com/styd/smart_kv"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
metadata
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_kv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Setyadi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Best practice of writing configurations by strictly allowing
|
14
|
-
keys.
|
13
|
+
description: Best practice of writing options or configurations by strictly allowing
|
14
|
+
and requiring keys.
|
15
15
|
email:
|
16
16
|
- a.styd@yahoo.com
|
17
17
|
executables: []
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".coveralls.yml"
|
21
22
|
- ".gitignore"
|
22
23
|
- ".rspec"
|
23
24
|
- ".travis.yml"
|
@@ -30,7 +31,6 @@ files:
|
|
30
31
|
- bin/console
|
31
32
|
- bin/setup
|
32
33
|
- lib/smart_kv.rb
|
33
|
-
- lib/smart_kv/macro.rb
|
34
34
|
- lib/smart_kv/register.rb
|
35
35
|
- lib/smart_kv/version.rb
|
36
36
|
- smart_kv.gemspec
|