cache_box 0.0.1.pre.preview6 → 0.0.1.pre.preview7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab194a6029ec0a9e3a9ac5cb8cdac124f7a06ab1d4066d50665bbdf9548a727a
4
- data.tar.gz: 06e3109c3d4f9437bd70768d21c69cc3252cc316f60a68072c5d1d8edb7fa4b6
3
+ metadata.gz: e95404d4c91af3089b9d7d5628a3449010007df8784043b3668bc028b3b54c44
4
+ data.tar.gz: f8fd2afe635ceab0504a2c2aef6b4a27417ad5bdde6564a7a39fd8af9b22840d
5
5
  SHA512:
6
- metadata.gz: 2229714e8ce3c5d92eb5a34cfdf047d6f0e315a56db856ea9c05bebacc22ca2c0881689d822df58c01f608cafd00d323b2e64f7decce15695ca671a1383fd1c1
7
- data.tar.gz: 83b5d7dac66492c48ea35c5ec82a70c249260d6e0f1961322ed9016ddafa1d0a7fecd6a3323db42cf7f9f2e29d6bced25d50d0117a76ac9af1215d17bb1e8639
6
+ metadata.gz: 5c5a41a763a413cef9e294c01e94c18808f3e817bdd4baff7ac4b936225b19f3b7785a43981b9167066123d3fd0d5673e81f5b54c71586a83e64fa39c2907a99
7
+ data.tar.gz: b2029aca5aa9a5a36a82e7010cb5959787ee214d7a0b1739b8575e95e5c3cfb7a842fde3c9264449d1dcb45dc926180d9eb3bbfd18edcb4b30d0ba2d04a50206
@@ -2,19 +2,26 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'cache_box'
5
- spec.version = '0.0.1-preview6'
5
+ spec.version = '0.0.1-preview7'
6
6
  spec.authors = ['Codruț Constantin Gușoi']
7
- spec.email = ['codrut.gusoi+git-commit@gmail.com']
7
+ spec.email = ['codrut.gusoi+rubygems.org@gmail.com']
8
8
 
9
- spec.summary = 'A simple, fast, and easy to use file backed cache.'
9
+ spec.summary = 'A simple, fast, and easy to use local cache.'
10
10
  spec.homepage = 'https://gitlab.com/sdwolfz/cache_box_rb'
11
- spec.license = 'BSD 3-clause'
11
+ spec.license = 'BSD-3-Clause'
12
+
13
+ spec.metadata = {
14
+ 'homepage_uri' => 'https://gitlab.com/sdwolfz/cache_box_rb',
15
+ 'source_code_uri' => 'https://gitlab.com/sdwolfz/cache_box_rb'
16
+ }
12
17
 
13
18
  spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
14
19
 
15
20
  spec.files = [
16
21
  'lib/cache_box.rb',
17
- 'lib/cache_box_chain.rb',
22
+ 'lib/cache_box/chain.rb',
23
+ 'lib/cache_box/file_storage.rb',
24
+ 'lib/cache_box/memory_storage.rb',
18
25
  'LICENSE',
19
26
  'cache_box.gemspec'
20
27
  ]
@@ -1,133 +1,109 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
- require_relative 'cache_box_chain'
4
+ require 'logger'
5
+
6
+ require_relative 'cache_box/chain'
7
+ require_relative 'cache_box/file_storage'
8
+ require_relative 'cache_box/memory_storage'
5
9
 
6
10
  class CacheBox
7
11
  # Input:
8
12
  #
9
- # namespace = String | Symbol # Default: :namespace
13
+ # namespace = String | Symbol # Default: 'namespace'
10
14
  #
11
15
  # Output: N/A
12
- def initialize(namespace = :namespace)
13
- validate!(namespace, 'namespace')
14
-
15
- @namespace = namespace
16
- @state = { complete: {}, result: {}, storage: {} }
17
- @root = File.join(Dir.pwd, '.cache')
18
- @directory = File.join(@root, @namespace.to_s)
19
- end
20
-
21
- # Input:
22
- #
23
- # namespace = String | Symbol # Default: :namespace
24
- #
25
- # Output: self
26
- def reset!(namespace = :namespace)
27
- initialize(namespace)
28
-
29
- self
30
- end
31
-
32
- # Input:
33
- #
34
- # name = String | Symbol # Default: :name
35
- # args = Array[...Object]
36
- # &block = Proc(*args)
37
- #
38
- # Output: Object # Anything the &block returns.
39
- def with(name = :name, *args)
40
- validate!(name, 'name')
41
-
42
- name = name.to_s
43
- file = File.join(@directory, name)
44
- result = find!(name, file)
45
- return result unless result.nil?
46
-
47
- result = yield(*args)
48
-
49
- @state[:complete][name] = true
50
- @state[:result][name] = result
51
- @state[:storage].delete(name)
52
- store!(name, file)
16
+ def initialize(namespace = nil, logger: nil, storage: nil)
17
+ validate_symbol_or_string!(namespace, 'namespace')
53
18
 
54
- result
19
+ @namespace = namespace&.to_s || 'namespace'
20
+ @logger = logger || Logger.new(STDOUT, level: Logger::INFO)
21
+ @storage = storage || FileStorage.new(namespace: @namespace)
22
+ @state = { result: {}, stash: {} }
55
23
  end
56
24
 
57
25
  # Input:
58
26
  #
59
- # name = String | Symbol # Default: :name
27
+ # name = String | Symbol # Default: 'name'
60
28
  # args = Array[...Object]
61
29
  # &block = Proc(Hash{...Object => Object}, *args)
62
30
  #
63
31
  # Output: Object # Anything the &block returns.
64
- def with_many(name = :name, *args)
65
- validate!(name, 'name')
32
+ def with(name = nil, *args)
33
+ validate_symbol_or_string!(name, 'name')
34
+ unless block_given?
35
+ raise(ArgumentError, 'The `:with` method requires a block')
36
+ end
66
37
 
67
- name = name.to_s
68
- file = File.join(@directory, name)
69
- result = find!(name, file)
70
- return result unless result.nil?
38
+ name = name&.to_s || 'name'
39
+ return @state[:result][name] if @state[:result].key?(name)
71
40
 
72
- storage = @state[:storage][name] || {}
73
- begin
74
- result = yield(storage, *args)
41
+ data = @storage.read!(name)
42
+ if data&.key?(:result)
43
+ @state[:result][name] = data[:result]
75
44
 
76
- @state[:complete][name] = true
77
- @state[:result][name] = result
78
- @state[:storage].delete(name)
79
- store!(name, file)
45
+ return data[:result]
46
+ elsif data&.key?(:stash)
47
+ @state[:stash][name] = data[:stash]
48
+ end
80
49
 
81
- result
50
+ stash = @state[:stash][name] || {}
51
+ begin
52
+ @state[:result][name] = yield(stash, *args)
82
53
  ensure
83
- unless @state[:complete][name]
84
- @state[:storage][name] = storage
54
+ if @state[:result].key?(name)
55
+ @state[:stash].delete(name)
56
+ @storage.write!(name, { result: @state[:result][name] })
57
+ else
58
+ @state[:stash][name] = stash
59
+ @storage.write!(name, { stash: stash })
85
60
  end
86
-
87
- store!(name, file)
88
61
  end
89
62
  end
90
63
 
91
64
  # Input:
92
65
  #
93
- # name = String | Symbol # Default: :name
66
+ # name = String | Symbol # Default: 'name'
94
67
  #
95
68
  # Output: true | false
96
- def has?(name = :name)
97
- validate!(name, 'name')
69
+ def has?(name = nil)
70
+ validate_symbol_or_string!(name, 'name')
98
71
 
99
- name = name.to_s
72
+ name = name&.to_s || 'name'
100
73
  return true if @state[:result].key?(name)
101
74
 
102
- file = File.join(@directory, name)
103
- load!(name, file)
75
+ data = @storage.read!(name)
104
76
 
105
- @state[:result].key?(name)
106
- end
107
-
108
- # Output: self
109
- def expire!
110
- @state = { complete: {}, result: {}, storage: {} }
111
- FileUtils.remove_entry_secure(@directory, true)
77
+ if data&.key?(:result)
78
+ @state[:result][name] = data[:result]
79
+ elsif data&.key?(:stash)
80
+ @state[:stash][name] = data[:stash]
81
+ end
112
82
 
113
- self
83
+ @state[:result].key?(name)
114
84
  end
115
85
 
116
86
  # Input:
117
87
  #
118
- # name = String | Symbol # Default: :name
88
+ # name = Array[String | Symbol] # Default: []
119
89
  #
120
90
  # Output: self
121
- def expire(name = :name)
122
- validate!(name, 'name')
91
+ def expire!(*names)
92
+ validate_array_of_symbol_or_string!(names, 'names')
123
93
 
124
- name = name.to_s
125
- @state[:complete].delete(name)
126
- @state[:result].delete(name)
127
- @state[:storage].delete(name)
94
+ if names.empty?
95
+ @state = { result: {}, stash: {} }
128
96
 
129
- file = File.join(@directory, name)
130
- FileUtils.remove_entry_secure(file, true)
97
+ @storage.reset!
98
+ else
99
+ names.each do |name|
100
+ name = name.to_s
101
+ @state[:result].delete(name)
102
+ @state[:stash].delete(name)
103
+
104
+ @storage.delete!(name)
105
+ end
106
+ end
131
107
 
132
108
  self
133
109
  end
@@ -140,8 +116,8 @@ class CacheBox
140
116
  # name = String
141
117
  #
142
118
  # Output: N/A
143
- def validate!(arg, name)
144
- return if arg.is_a?(Symbol) || arg.is_a?(String)
119
+ def validate_symbol_or_string!(arg, name)
120
+ return if arg.nil? || arg.is_a?(Symbol) || arg.is_a?(String)
145
121
 
146
122
  klass = arg.class
147
123
  value = arg.inspect
@@ -151,47 +127,21 @@ class CacheBox
151
127
 
152
128
  # Input:
153
129
  #
130
+ # arg = Array[String | Symbol]
154
131
  # name = String
155
- # file = String # Path
156
132
  #
157
133
  # Output: N/A
158
- def load!(name, file)
159
- if File.exist?(file)
160
- data = Marshal.load(File.read(file))
134
+ def validate_array_of_symbol_or_string!(args, name)
135
+ args.each do |arg|
136
+ next if arg.is_a?(Symbol) || arg.is_a?(String)
161
137
 
162
- @state[:complete][name] = data[:complete] if data.key?(:complete)
163
- @state[:result][name] = data[:result] if data.key?(:result)
164
- @state[:storage][name] = data[:storage] if data.key?(:storage)
165
- end
166
- end
138
+ klass = arg.class
139
+ value = arg.inspect
167
140
 
168
- # Input:
169
- #
170
- # name = String
171
- # file = String # Path
172
- #
173
- # Output: Object # Anything
174
- def find!(name, file)
175
- load!(name, file)
176
-
177
- @state[:result][name]
178
- end
179
-
180
- # Input:
181
- #
182
- # file = String # Path
183
- #
184
- # Output: N/A
185
- def store!(name, file)
186
- data = {}
187
- data[:complete] = @state[:complete][name] if @state[:complete][name]
188
- data[:result] = @state[:result][name] if @state[:result][name]
189
- data[:storage] = @state[:storage][name] if @state[:storage][name] && !@state[:complete][name]
190
-
191
- content = Marshal.dump(data)
192
-
193
- directory = File.dirname(file)
194
- FileUtils.mkdir_p(directory) unless Dir.exist?(directory)
195
- File.write(file, content)
141
+ raise(
142
+ ArgumentError,
143
+ "#{name} must each be Symbol or String, got #{klass}: #{value} in #{args}"
144
+ )
145
+ end
196
146
  end
197
147
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ class Chain
5
+ # Input:
6
+ #
7
+ # namespace = String | Symbol # Default: 'namespace'
8
+ #
9
+ # Output: N/A
10
+ def initialize(namespace = nil, logger: nil, storage: nil)
11
+ namespace ||= 'namespace'
12
+ logger ||= Logger.new(STDOUT, level: Logger::INFO)
13
+ storage ||= FileStorage.new(namespace: namespace)
14
+
15
+ @cache = ::CacheBox.new(namespace, logger: logger, storage: storage)
16
+ @chain = []
17
+ @set = Set.new
18
+ end
19
+
20
+ # Input:
21
+ #
22
+ # name = String | Symbol
23
+ # args = Array[...Object]
24
+ # &block = Proc(Hash{...Object => Object}, *args)
25
+ #
26
+ # Output: self
27
+ def add(name, *args, &block)
28
+ validate_add!(name, &block)
29
+
30
+ string_name = name.to_s
31
+ if @set.include?(string_name)
32
+ raise(
33
+ ArgumentError,
34
+ "Chain already contains a step named #{name.inspect}"
35
+ )
36
+ else
37
+ @set << string_name
38
+ end
39
+
40
+ @chain.push(
41
+ [name, args, proc { |*all| @cache.with(string_name, *all, &block) }]
42
+ )
43
+
44
+ self
45
+ end
46
+
47
+ # Output: Object # Anything the last block in the chain returns.
48
+ def run!
49
+ work = []
50
+
51
+ @chain.reverse_each do |name, args, callable|
52
+ work.push([name, args, callable])
53
+
54
+ break if @cache.has?(name)
55
+ end
56
+
57
+ result = nil
58
+ work.reverse_each do |_name, args, callable|
59
+ input = []
60
+ input << result if result
61
+ input += args if args
62
+
63
+ result = callable.call(*input)
64
+ end
65
+
66
+ result
67
+ end
68
+
69
+ # Input:
70
+ #
71
+ # name = Array[String | Symbol] # Default: []
72
+ #
73
+ # Output: self
74
+ def expire!(*names)
75
+ @cache.expire!(*names)
76
+
77
+ self
78
+ end
79
+
80
+ private
81
+
82
+ # Input:
83
+ #
84
+ # name = String | Symbol
85
+ # &block = Proc
86
+ #
87
+ # Output: N/A
88
+ def validate_add!(name, &block)
89
+ unless name.is_a?(Symbol) || name.is_a?(String)
90
+ klass = name.class
91
+ value = name.inspect
92
+
93
+ raise(
94
+ ArgumentError,
95
+ "name must be a Symbol or String, got #{klass}: #{value}"
96
+ )
97
+ end
98
+
99
+ return unless block.nil?
100
+
101
+ raise(ArgumentError, 'The `:add` method requires a block')
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ # A storage backed by files.
5
+ class FileStorage
6
+ # Input:
7
+ #
8
+ # namespace = Symbol | String # Default: 'namespace'
9
+ # path = String # Path; Default: nil
10
+ #
11
+ # Output: N/A
12
+ def initialize(namespace: nil, path: nil)
13
+ validate_symbol_or_string!(namespace, 'namespace')
14
+ validate_string!(path, 'path')
15
+
16
+ @namespace = namespace.to_s || 'namespace'
17
+
18
+ root = path || File.join(Dir.pwd, '.cache')
19
+ @path = File.join(root, @namespace)
20
+ end
21
+
22
+ # Output: self
23
+ def reset!
24
+ FileUtils.remove_entry_secure(@path, true)
25
+
26
+ self
27
+ end
28
+
29
+ # Reads the content.
30
+ #
31
+ # Input:
32
+ #
33
+ # name = String
34
+ #
35
+ # Output: Object # Anything
36
+ def read!(name)
37
+ validate_string!(name, 'name')
38
+
39
+ file = File.join(@path, name)
40
+ return unless File.exist?(file)
41
+
42
+ Marshal.load(File.read(file))
43
+ end
44
+
45
+ # Input:
46
+ #
47
+ # name = String
48
+ # data = Object # Anything
49
+ #
50
+ # Output: self
51
+ def write!(name, data)
52
+ validate_string!(name, 'name')
53
+
54
+ FileUtils.mkdir_p(@path) unless Dir.exist?(@path)
55
+
56
+ content = Marshal.dump(data)
57
+ file = File.join(@path, name)
58
+
59
+ File.write(file, content)
60
+
61
+ self
62
+ end
63
+
64
+ # Input:
65
+ #
66
+ # name = String
67
+ #
68
+ # Output: self
69
+ def delete!(name)
70
+ validate_string!(name, 'name')
71
+
72
+ file = File.join(@path, name)
73
+ FileUtils.remove_entry_secure(file, true)
74
+
75
+ self
76
+ end
77
+
78
+ # Input:
79
+ #
80
+ # name = String
81
+ #
82
+ # Output: true | false
83
+ def has?(name)
84
+ validate_string!(name, 'name')
85
+
86
+ file = File.join(@path, name)
87
+ File.file?(file)
88
+ end
89
+
90
+ private
91
+
92
+ def validate_symbol_or_string!(arg, name)
93
+ return if arg.nil? || arg.is_a?(Symbol) || arg.is_a?(String)
94
+
95
+ klass = arg.class
96
+ value = arg.inspect
97
+
98
+ raise(
99
+ ArgumentError,
100
+ "#{name} must be a Symbol or String, got #{klass}: #{value}"
101
+ )
102
+ end
103
+
104
+ def validate_string!(arg, name)
105
+ return if arg.nil? || arg.is_a?(String)
106
+
107
+ klass = arg.class
108
+ value = arg.inspect
109
+
110
+ raise(
111
+ ArgumentError,
112
+ "#{name} must be a String, got #{klass}: #{value}"
113
+ )
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CacheBox
4
+ # A storage backed by an in memory Hash.
5
+ class MemoryStorage
6
+ # Accepts a Hash or any Hash-like object as argument. Will use a plain Hash
7
+ # if none provided.
8
+ #
9
+ # Input:
10
+ #
11
+ # state = Hash{...Object => Object} # Default: nil
12
+ #
13
+ # Output: N/A
14
+ def initialize(state = nil)
15
+ validate!(state)
16
+
17
+ @state = state || {}
18
+ end
19
+
20
+ # Accepts a Hash or any Hash-like object as argument. Will use a plain Hash
21
+ # if none provided.
22
+ #
23
+ # Input:
24
+ #
25
+ # state = Hash{...Object => Object}
26
+ #
27
+ # Output: self
28
+ def reset!(state = nil)
29
+ initialize(state)
30
+
31
+ self
32
+ end
33
+
34
+ # Input:
35
+ #
36
+ # name = String
37
+ #
38
+ # Output: Object # Anything
39
+ def read!(name)
40
+ validate_string!(name, 'name')
41
+
42
+ @state[name]
43
+ end
44
+
45
+ # Input:
46
+ #
47
+ # name = String
48
+ # data = Object # Anything
49
+ #
50
+ # Output: self
51
+ def write!(name, data)
52
+ validate_string!(name, 'name')
53
+
54
+ @state[name] = data
55
+
56
+ self
57
+ end
58
+
59
+ # Input:
60
+ #
61
+ # name = String
62
+ #
63
+ # Output: self
64
+ def delete!(name)
65
+ validate_string!(name, 'name')
66
+
67
+ @state.delete(name)
68
+
69
+ self
70
+ end
71
+
72
+ # Input:
73
+ #
74
+ # name = String
75
+ #
76
+ # Output: true | false
77
+ def has?(name)
78
+ validate_string!(name, 'name')
79
+
80
+ @state.key?(name)
81
+ end
82
+
83
+ private
84
+
85
+ # Input:
86
+ #
87
+ # state = Object # Anything
88
+ #
89
+ # Output: N/A
90
+ def validate!(state)
91
+ return if state.nil? || state.is_a?(Hash)
92
+
93
+ validate_get!(state)
94
+ validate_set!(state)
95
+ validate_delete!(state)
96
+ validate_key!(state)
97
+ end
98
+
99
+ # Input:
100
+ #
101
+ # state = Object # Anything
102
+ #
103
+ # Output: N/A
104
+ def validate_get!(state)
105
+ unless state.respond_to?(:[])
106
+ raise(ArgumentError, 'Given state object does not respond to `:[]`')
107
+ end
108
+
109
+ arity = state.method(:[]).arity
110
+ unless arity == 1
111
+ raise(
112
+ ArgumentError,
113
+ "Given state object's `:[]` method arity must be 1, got: #{arity}"
114
+ )
115
+ end
116
+ end
117
+
118
+ # Input:
119
+ #
120
+ # state = Object # Anything
121
+ #
122
+ # Output: N/A
123
+ def validate_set!(state)
124
+ unless state.respond_to?(:[]=)
125
+ raise(ArgumentError, 'Given state object does not respond to `:[]=`')
126
+ end
127
+
128
+ arity = state.method(:[]=).arity
129
+ unless arity == 2
130
+ raise(
131
+ ArgumentError,
132
+ "Given state object's `:[]=` method arity must be 2, got: #{arity}"
133
+ )
134
+ end
135
+ end
136
+
137
+ # Input:
138
+ #
139
+ # state = Object # Anything
140
+ #
141
+ # Output: N/A
142
+ def validate_delete!(state)
143
+ unless state.respond_to?(:delete)
144
+ raise(ArgumentError, 'Given state object does not respond to `delete`')
145
+ end
146
+
147
+ arity = state.method(:delete).arity
148
+ unless arity == 1
149
+ raise(
150
+ ArgumentError,
151
+ "Given state object's `:delete` method arity must be 1, got: #{arity}"
152
+ )
153
+ end
154
+ end
155
+
156
+ # Input:
157
+ #
158
+ # state = Object # Anything
159
+ #
160
+ # Output: N/A
161
+ def validate_key!(state)
162
+ unless state.respond_to?(:key?)
163
+ raise(ArgumentError, 'Given state object does not respond to `:key?`')
164
+ end
165
+
166
+ arity = state.method(:key?).arity
167
+ unless arity == 1
168
+ raise(
169
+ ArgumentError,
170
+ "Given state object's `:key?` method arity must be 1, got: #{arity}"
171
+ )
172
+ end
173
+ end
174
+
175
+ # Input:
176
+ #
177
+ # arg = String
178
+ # name = String
179
+ #
180
+ # Output: N/A
181
+ def validate_string!(arg, name)
182
+ return if arg.nil? || arg.is_a?(String)
183
+
184
+ klass = arg.class
185
+ value = arg.inspect
186
+
187
+ raise(
188
+ ArgumentError,
189
+ "#{name} must be a String, got #{klass}: #{value}"
190
+ )
191
+ end
192
+ end
193
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_box
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre.preview6
4
+ version: 0.0.1.pre.preview7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Codruț Constantin Gușoi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-19 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -66,9 +66,9 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.88'
69
- description:
69
+ description:
70
70
  email:
71
- - codrut.gusoi+git-commit@gmail.com
71
+ - codrut.gusoi+rubygems.org@gmail.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
@@ -76,12 +76,16 @@ files:
76
76
  - LICENSE
77
77
  - cache_box.gemspec
78
78
  - lib/cache_box.rb
79
- - lib/cache_box_chain.rb
79
+ - lib/cache_box/chain.rb
80
+ - lib/cache_box/file_storage.rb
81
+ - lib/cache_box/memory_storage.rb
80
82
  homepage: https://gitlab.com/sdwolfz/cache_box_rb
81
83
  licenses:
82
- - BSD 3-clause
83
- metadata: {}
84
- post_install_message:
84
+ - BSD-3-Clause
85
+ metadata:
86
+ homepage_uri: https://gitlab.com/sdwolfz/cache_box_rb
87
+ source_code_uri: https://gitlab.com/sdwolfz/cache_box_rb
88
+ post_install_message:
85
89
  rdoc_options: []
86
90
  require_paths:
87
91
  - lib
@@ -96,8 +100,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
100
  - !ruby/object:Gem::Version
97
101
  version: 1.3.1
98
102
  requirements: []
99
- rubygems_version: 3.1.3
100
- signing_key:
103
+ rubygems_version: 3.1.2
104
+ signing_key:
101
105
  specification_version: 4
102
- summary: A simple, fast, and easy to use file backed cache.
106
+ summary: A simple, fast, and easy to use local cache.
103
107
  test_files: []
@@ -1,177 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CacheBox
4
- class Chain
5
- # Input:
6
- #
7
- # namespace = String | Symbol # Default: :namespace
8
- #
9
- # Output: N/A
10
- def initialize(namespace = :namespace)
11
- @cache = ::CacheBox.new(namespace)
12
- @chain = []
13
- end
14
-
15
- # Input:
16
- #
17
- # namespace = String | Symbol # Default: :namespace
18
- #
19
- # Output: self
20
- def reset!(namespace = :namespace)
21
- @cache.reset!(namespace)
22
- @chain = []
23
-
24
- self
25
- end
26
-
27
- # Input:
28
- #
29
- # name = String | Symbol
30
- # args = Array[...Object]
31
- # &block = Proc(*args)
32
- #
33
- # Output: self
34
- def chain(name, *args, &block)
35
- validate_chain!(name, &block)
36
-
37
- @chain.push(
38
- [name, args, proc { |*all| @cache.with(name, *all, &block) }]
39
- )
40
-
41
- self
42
- end
43
-
44
- # Input:
45
- #
46
- # name = String | Symbol
47
- # args = Array[...Object]
48
- # &block = Proc(Hash{...Object => Object}, *args)
49
- #
50
- # Output: self
51
- def chain_many(name, *args, &block)
52
- validate_chain!(name, &block)
53
-
54
- @chain.push(
55
- [name, args, proc { |*all| @cache.with_many(name, *all, &block) }]
56
- )
57
-
58
- self
59
- end
60
-
61
- # Input:
62
- #
63
- # all = nil | :all # Default: nil
64
- #
65
- # Output: Object # Anything the last block in the chain returns.
66
- def run!(all = nil)
67
- validate_run!(all)
68
-
69
- if all
70
- run_all
71
- else
72
- run_chain
73
- end
74
- end
75
-
76
- # Output: self
77
- def expire!
78
- @cache.expire!
79
-
80
- self
81
- end
82
-
83
- # Input:
84
- #
85
- # names = ...(String | Symbol)
86
- #
87
- # Output: self
88
- def expire(*names)
89
- names.each do |name|
90
- @cache.expire(name)
91
- end
92
-
93
- self
94
- end
95
-
96
- private
97
-
98
- # Input:
99
- #
100
- # name = String | Symbol
101
- # &block = Proc
102
- #
103
- # Output: N/A
104
- def validate_chain!(name, &block)
105
- unless name.is_a?(Symbol) || name.is_a?(String)
106
- klass = name.class
107
- value = name.inspect
108
-
109
- raise(
110
- ArgumentError,
111
- "name must be a Symbol or a String, got #{klass}: #{value}"
112
- )
113
- end
114
-
115
- return unless block.nil?
116
-
117
- raise(
118
- ArgumentError,
119
- 'The `#chain/2` method needs to be called with a block'
120
- )
121
- end
122
-
123
- # Input:
124
- #
125
- # arg = nil | :all
126
- #
127
- # Output: N/A
128
- def validate_run!(arg)
129
- return if arg.nil? || arg == :all
130
-
131
- klass = arg.class
132
- value = arg.inspect
133
-
134
- raise(
135
- ArgumentError,
136
- 'The `run!` method only accepts `nil` or the Symbol `:all` as an ' \
137
- "argument, got #{klass}: #{value}"
138
- )
139
- end
140
-
141
- # Output: Object # Anything the last callable returns.
142
- def run_all
143
- result = nil
144
- @chain.each do |_name, args, callable|
145
- input = []
146
- input << result if result
147
- input += args if args
148
-
149
- result = callable.call(*input)
150
- end
151
-
152
- result
153
- end
154
-
155
- # Output: Object # Anything the last executed callable returns.
156
- def run_chain
157
- work = []
158
-
159
- @chain.reverse_each do |name, args, callable|
160
- work.push([name, args, callable])
161
-
162
- break if @cache.has?(name)
163
- end
164
-
165
- result = nil
166
- work.reverse_each do |_name, args, callable|
167
- input = []
168
- input << result if result
169
- input += args if args
170
-
171
- result = callable.call(*input)
172
- end
173
-
174
- result
175
- end
176
- end
177
- end