clean-hash 0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8455736b6df4f0682b955aa5aa0d70a313b60a4ca01a51029e55e78d4d52b4bf
4
+ data.tar.gz: 426946203c65e097eaefcf354e6af8bb19c59e1dc424384f5831e6420ae41bb3
5
+ SHA512:
6
+ metadata.gz: d50a1d7af39b6e0980c7141c3ad5ae1e9c76db707b2b0a2e8191a3062f16169a305aab6e8710ca61c0504b388a893ebc66de3ac4edc19b8801f79068bfa463af
7
+ data.tar.gz: bbced94df41e9ddfd18b5b8781d8c23c77530f4d5e3951215f86860eb99bc605da77971d72576b4edd157d0f013e72eda345fc937270e60206a40e39a201ceba
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,7 @@
1
+ require 'hashie'
2
+
3
+ require_relative 'clean-hash/base'
4
+ require_relative 'clean-hash/deep_merge'
5
+ require_relative 'clean-hash/mutex_hash'
6
+ require_relative 'clean-hash/hash_pollute'
7
+
@@ -0,0 +1,105 @@
1
+ class CleanHash
2
+ def initialize data, mode=nil
3
+ @data = data
4
+ @mode = mode
5
+
6
+ case mode
7
+ when :safe
8
+ @is_safe = true
9
+ else
10
+ @is_strict = true if mode
11
+ end
12
+ end
13
+
14
+ # for debug
15
+ def to_json
16
+ JSON.pretty_generate @data
17
+ end
18
+
19
+ # for puts
20
+ def to_ary
21
+ [@data]
22
+ end
23
+
24
+ def [] key
25
+ __value_for key.to_s
26
+ end
27
+
28
+ def []= key, value
29
+ __error_set
30
+ end
31
+
32
+ def key? name
33
+ __value_for name
34
+ true
35
+ rescue NoMethodError
36
+ false
37
+ end
38
+
39
+ def keys
40
+ @data.keys
41
+ end
42
+
43
+ def values
44
+ @data.values
45
+ end
46
+
47
+ def to_h
48
+ @data
49
+ end
50
+
51
+ def method_missing name, *args
52
+ m = name.to_s
53
+
54
+ if m.end_with?('=')
55
+ m = m.sub('=', '')
56
+
57
+ __error_set if @is_strict && !key?(m)
58
+
59
+ value = args.first
60
+
61
+ if @is_safe
62
+ value = value.to_s if value.is_a?(Symbol)
63
+
64
+ unless value.nil? || value.is_a?(Hash) || value.is_a?(Numeric) || value.is_a?(String)
65
+ raise ArgumentError.new('Unsupported safe type: %s' % value.class)
66
+ end
67
+ end
68
+
69
+ m = m.to_sym if @data[m].nil?
70
+
71
+ @data[m] = value
72
+ elsif m.end_with?('?')
73
+ begin
74
+ !__value_for(m.sub('?', '')).nil?
75
+ rescue NoMethodError
76
+ false
77
+ end
78
+ else
79
+ __value_for m
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def __value_for name
86
+ data = @data[name.to_s]
87
+ data = @data[name.to_sym] if data.nil?
88
+
89
+ if data.nil?
90
+ if @is_strict && !keys.include?(name.to_sym)
91
+ raise NoMethodError, 'Clean hash: key "%s" not found' % name
92
+ else
93
+ nil
94
+ end
95
+ elsif data.is_a?(Hash)
96
+ CleanHash.new data, @mode
97
+ else
98
+ data
99
+ end
100
+ end
101
+
102
+ def __error_set
103
+ raise NoMethodError, 'Clean hash: setting a key value is not allowedß'
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+ class CleanHash
2
+ class DeepMerge < Hash
3
+ include ::Hashie::Extensions::DeepMerge
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ class CleanHash
2
+ def self.pollute!
3
+ ::Hash.class_eval do
4
+ # merge but to not overwrite keys
5
+ def deep_merge hash
6
+ klass = ::CleanHash::DeepMerge
7
+ klass[deep_clone].deep_merge klass[hash]
8
+ end
9
+
10
+ # true clone of the hash with 0 references to the old one
11
+ def deep_clone
12
+ Marshal.load(Marshal.dump(self))
13
+ end
14
+
15
+ def to_ch mode=nil
16
+ if mode.is_a?(Array)
17
+ for key in keys
18
+ raise ArgumentError, 'CleanHash key "%s" not allowed' % key unless mode.include?(key)
19
+ end
20
+
21
+ for key in mode
22
+ self[key] = nil unless key?(key)
23
+ end
24
+
25
+ ::CleanHash.new self, :strict
26
+ else
27
+ supported = %i{safe mutex strict}
28
+ raise ArgumentError, 'Unsupported type "%s", supported: %s' % [mode, supported] if mode && !supported.include?(mode)
29
+
30
+ if mode == :mutex
31
+ ::CleanHash::MutexHash.new self
32
+ else
33
+ ::CleanHash.new self, mode
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ ::Array.class_eval do
40
+ # coverts keys to empty hash methods and returns read_only hash
41
+ def to_ch strict=false
42
+ hash = inject({}) { |h, key| h[key] = nil; h }
43
+ ::CleanHash.new hash, :strict
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,20 @@
1
+ # Thread safe hash
2
+ class CleanHash
3
+ class MutexHash
4
+ MUTEX = Mutex.new
5
+
6
+ def initialize name=nil
7
+ @data ||= {}
8
+ end
9
+
10
+ def [] name
11
+ @data[name.to_sym]
12
+ end
13
+
14
+ def []= name, value
15
+ MUTEX.synchronize do
16
+ @data[name.to_sym] = value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ require_relative '../clean-hash'
2
+
3
+ CleanHash.pollute!
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clean-hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Dino Reic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hashie
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ description: Gem provides simple access to common Ruby hash types
28
+ email: reic.dino@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - "./.version"
34
+ - "./lib/clean-hash.rb"
35
+ - "./lib/clean-hash/base.rb"
36
+ - "./lib/clean-hash/deep_merge.rb"
37
+ - "./lib/clean-hash/hash_pollute.rb"
38
+ - "./lib/clean-hash/mutex_hash.rb"
39
+ - "./lib/clean-hash/pollute.rb"
40
+ homepage: https://github.com/dux/clean-hash
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.0.6
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Hash with indifferent access, mash, strict config mode, deep copy
63
+ test_files: []