snaky_hash 1.0.1 → 2.0.0
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/CHANGELOG.md +12 -0
- data/README.md +40 -2
- data/lib/snaky_hash/snake.rb +64 -43
- data/lib/snaky_hash/string_keyed.rb +5 -0
- data/lib/snaky_hash/symbol_keyed.rb +5 -0
- data/lib/snaky_hash/version.rb +1 -1
- data/lib/snaky_hash.rb +3 -0
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5995aa841b28557864f23d3d2e08c861d5854805c8eb8bed7e68719b89412a44
|
4
|
+
data.tar.gz: 035cd4ab1644739be5ab0bfcea8388bc37110e4cd4b3d495b70715652bd3cd35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2ee23b5884158fe2642c73b2d00665900e509a606942008cc2e02aee79becd46d01f71e16e4702d027f9961cbd24f5892ecf4bf06915344def299b4488f9324
|
7
|
+
data.tar.gz: fa72da01cb55b92152f9274f3dcb2920c6948d73ed11d0d3af70cfa86b713985b73746e3a8b60f0cf8873e8fea62dbd4dcc9d659e329ccbaad32ff901052ea34
|
data/CHANGELOG.md
CHANGED
@@ -12,6 +12,18 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
|
|
12
12
|
|
13
13
|
## [Unreleased]
|
14
14
|
|
15
|
+
## [2.0.0] - 2022-08-29
|
16
|
+
### Changed
|
17
|
+
- **BREAKING**: `SnakeHash::Snake` is now a mixin, now with support for symbol or string keys
|
18
|
+
```ruby
|
19
|
+
class MySnakedHash < Hashie::Mash
|
20
|
+
include SnakyHash::Snake.new(key_type: :string) # or :symbol
|
21
|
+
end
|
22
|
+
```
|
23
|
+
### Added
|
24
|
+
- `SnakyHash::StringKeyed`: a Hashie::Mash class with snake-cased String keys
|
25
|
+
- `SnakyHash::SymbolKeyed`: a Hashie::Mash class with snake-cased Symbol keys
|
26
|
+
|
15
27
|
## [1.0.1] - 2022-08-26
|
16
28
|
### Added
|
17
29
|
- Missing LICENSE.txt file to release
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ and provide a nice psuedo-object interface.
|
|
5
5
|
|
6
6
|
It has its roots in the `Rash` (specifically the [`rash_alt`](https://github.com/shishi/rash_alt) flavor), which is a special `Mash`, made popular by the `hashie` gem.
|
7
7
|
|
8
|
-
`SnakyHash::Snake`
|
8
|
+
Classes that include `SnakyHash::Snake` should inherit from `Hashie::Mash`.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -19,7 +19,45 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
19
19
|
|
20
20
|
## Usage
|
21
21
|
|
22
|
-
|
22
|
+
```ruby
|
23
|
+
class MySnakedHash < Hashie::Mash
|
24
|
+
include SnakyHash::Snake.new(key_type: :string) # or :symbol
|
25
|
+
end
|
26
|
+
|
27
|
+
snake = MySnakedHash.new(a: 'a', 'b' => 'b', 2 => 2, 'VeryFineHat' => 'Feathers')
|
28
|
+
snake.a # => 'a'
|
29
|
+
snake.b # => 'b'
|
30
|
+
snake[2] # 2
|
31
|
+
snake.very_fine_hat # => 'Feathers'
|
32
|
+
snake[:very_fine_hat] # => 'Feathers'
|
33
|
+
snake['very_fine_hat'] # => 'Feathers'
|
34
|
+
```
|
35
|
+
|
36
|
+
Note above that you can access the values via the string, or symbol.
|
37
|
+
The `key_type` determines how the key is actually stored, but the hash acts as "indifferent".
|
38
|
+
Note also that keys which do not respond to `to_sym`, because they don't have a natural conversion to a Symbol,
|
39
|
+
are left as-is.
|
40
|
+
|
41
|
+
### Stranger Things
|
42
|
+
|
43
|
+
I don't recommend using these features... but they exist (for now).
|
44
|
+
You can still access the original un-snaked camel keys.
|
45
|
+
And through them you can even use un-snaked camel methods.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
snake.key?('VeryFineHat') # => true
|
49
|
+
snake['VeryFineHat'] # => 'Feathers'
|
50
|
+
snake.VeryFineHat # => 'Feathers', PLEASE don't do this!!!
|
51
|
+
snake['VeryFineHat'] = 'pop' # Please don't do this... you'll get a warning, and it works (for now), but no guarantees.
|
52
|
+
# WARN -- : You are setting a key that conflicts with a built-in method MySnakedHash#VeryFineHat defined in MySnakedHash. This can cause unexpected behavior when accessing the key as a property. You can still access the key via the #[] method.
|
53
|
+
# => "pop"
|
54
|
+
snake.very_fine_hat = 'pop' # => 'pop', do this instead!!!
|
55
|
+
snake.very_fine_hat # => 'pop'
|
56
|
+
snake[:very_fine_hat] = 'moose' # => 'moose', or do this instead!!!
|
57
|
+
snake.very_fine_hat # => 'moose'
|
58
|
+
snake['very_fine_hat'] = 'cheese' # => 'cheese', or do this instead!!!
|
59
|
+
snake.very_fine_hat # => 'cheese'
|
60
|
+
```
|
23
61
|
|
24
62
|
## Development
|
25
63
|
|
data/lib/snaky_hash/snake.rb
CHANGED
@@ -1,51 +1,72 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# This is a module-class hybrid.
|
2
|
+
#
|
3
|
+
# Hashie's standard SymbolizeKeys is similar to the functionality we want.
|
4
|
+
# ... but not quite. We need to support both String (for oauth2) and Symbol keys (for oauth).
|
5
|
+
# include Hashie::Extensions::Mash::SymbolizeKeys
|
3
6
|
module SnakyHash
|
4
|
-
class Snake <
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
protected
|
9
|
-
|
10
|
-
# Converts a key to a string,
|
11
|
-
# but only if it is able to be converted to a symbol.
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
# @param [<K>] key the key to attempt convert to a symbol
|
15
|
-
# @return [String, K]
|
16
|
-
def convert_key(key)
|
17
|
-
key.respond_to?(:to_sym) ? underscore_string(key.to_s) : key
|
7
|
+
class Snake < Module
|
8
|
+
def initialize(key_type: :string)
|
9
|
+
super()
|
10
|
+
@key_type = key_type
|
18
11
|
end
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def convert_value(val, duping = false) #:nodoc:
|
24
|
-
case val
|
25
|
-
when self.class
|
26
|
-
val.dup
|
27
|
-
when ::Hash
|
28
|
-
val = val.dup if duping
|
29
|
-
self.class.new(val)
|
30
|
-
when ::Array
|
31
|
-
val.collect { |e| convert_value(e) }
|
32
|
-
else
|
33
|
-
val
|
34
|
-
end
|
13
|
+
def included(base)
|
14
|
+
conversions_module = SnakyModulizer.to_mod(@key_type)
|
15
|
+
base.include(conversions_module)
|
35
16
|
end
|
36
17
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
18
|
+
module SnakyModulizer
|
19
|
+
def self.to_mod(key_type)
|
20
|
+
Module.new do
|
21
|
+
# Converts a key to a symbol, or a string, depending on key_type,
|
22
|
+
# but only if it is able to be converted to a symbol,
|
23
|
+
# and after underscoring it.
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @param [<K>] key the key to attempt convert to a symbol
|
27
|
+
# @return [Symbol, K]
|
28
|
+
|
29
|
+
case key_type
|
30
|
+
when :string then
|
31
|
+
define_method(:convert_key) { |key| key.respond_to?(:to_sym) ? underscore_string(key.to_s) : key }
|
32
|
+
when :symbol then
|
33
|
+
define_method(:convert_key) { |key| key.respond_to?(:to_sym) ? underscore_string(key.to_s).to_sym : key }
|
34
|
+
else
|
35
|
+
raise ArgumentError, "SnakyHash: Unhandled key_type: #{key_type}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Unlike its parent Mash, a SnakyHash::Snake will convert other
|
39
|
+
# Hashie::Hash values to a SnakyHash::Snake when assigning
|
40
|
+
# instead of respecting the existing subclass
|
41
|
+
define_method :convert_value do |val, duping = false| #:nodoc:
|
42
|
+
case val
|
43
|
+
when self.class
|
44
|
+
val.dup
|
45
|
+
when ::Hash
|
46
|
+
val = val.dup if duping
|
47
|
+
self.class.new(val)
|
48
|
+
when ::Array
|
49
|
+
val.collect { |e| convert_value(e) }
|
50
|
+
else
|
51
|
+
val
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# converts a camel_cased string to a underscore string
|
56
|
+
# subs spaces with underscores, strips whitespace
|
57
|
+
# Same way ActiveSupport does string.underscore
|
58
|
+
define_method :underscore_string do |str|
|
59
|
+
str.to_s.strip
|
60
|
+
.tr(" ", "_")
|
61
|
+
.gsub(/::/, "/")
|
62
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
63
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
64
|
+
.tr("-", "_")
|
65
|
+
.squeeze("_")
|
66
|
+
.downcase
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
49
70
|
end
|
50
71
|
end
|
51
72
|
end
|
data/lib/snaky_hash/version.rb
CHANGED
data/lib/snaky_hash.rb
CHANGED
@@ -6,7 +6,10 @@ require "version_gem"
|
|
6
6
|
|
7
7
|
require_relative "snaky_hash/version"
|
8
8
|
require_relative "snaky_hash/snake"
|
9
|
+
require_relative "snaky_hash/string_keyed"
|
10
|
+
require_relative "snaky_hash/symbol_keyed"
|
9
11
|
|
12
|
+
# This is the namespace for this gem
|
10
13
|
module SnakyHash
|
11
14
|
end
|
12
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snaky_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '8.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-block_is_expected
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: 'A Hashie::Mash joint to make #snakelife better'
|
84
98
|
email:
|
85
99
|
- peter.boling@gmail.com
|
@@ -95,16 +109,18 @@ files:
|
|
95
109
|
- SECURITY.md
|
96
110
|
- lib/snaky_hash.rb
|
97
111
|
- lib/snaky_hash/snake.rb
|
112
|
+
- lib/snaky_hash/string_keyed.rb
|
113
|
+
- lib/snaky_hash/symbol_keyed.rb
|
98
114
|
- lib/snaky_hash/version.rb
|
99
115
|
homepage: https://gitlab.com/oauth-xx/snaky_hash
|
100
116
|
licenses:
|
101
117
|
- MIT
|
102
118
|
metadata:
|
103
119
|
homepage_uri: https://gitlab.com/oauth-xx/snaky_hash
|
104
|
-
source_code_uri: https://gitlab.com/oauth-xx/snaky_hash/-/tree/
|
105
|
-
changelog_uri: https://gitlab.com/oauth-xx/snaky_hash/-/blob/
|
120
|
+
source_code_uri: https://gitlab.com/oauth-xx/snaky_hash/-/tree/v2.0.0
|
121
|
+
changelog_uri: https://gitlab.com/oauth-xx/snaky_hash/-/blob/v2.0.0/CHANGELOG.md
|
106
122
|
bug_tracker_uri: https://gitlab.com/oauth-xx/snaky_hash/-/issues
|
107
|
-
documentation_uri: https://www.rubydoc.info/gems/snaky_hash/
|
123
|
+
documentation_uri: https://www.rubydoc.info/gems/snaky_hash/2.0.0
|
108
124
|
wiki_uri: https://gitlab.com/oauth-xx/snaky_hash/-/wikis/home
|
109
125
|
rubygems_mfa_required: 'true'
|
110
126
|
post_install_message:
|