bitary 0.1.5 → 0.1.7
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/.rubocop.yml +2 -0
- data/CHANGELOG.md +8 -0
- data/lib/bitary/bitwarr.rb +57 -110
- data/lib/bitary/decorator/single_method.rb +0 -1
- data/lib/bitary/decorator.rb +0 -1
- data/lib/bitary/handler/append.rb +0 -11
- data/lib/bitary/handler/get.rb +0 -17
- data/lib/bitary/handler/set.rb +0 -17
- data/lib/bitary/handler/unset.rb +3 -21
- data/lib/bitary/handler.rb +0 -11
- data/lib/bitary/version.rb +1 -1
- data/lib/bitary.rb +35 -11
- metadata +2 -4
- data/lib/bitary/decorator/kwargs_validator.rb +0 -174
- data/lib/bitary/decorator/single_method/truthy_enforcer.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 537a58c702f90bfeade22439d4134d921df709d4d474279f29adae869ff08b0d
|
4
|
+
data.tar.gz: 90910632d7a7f40f89774a8d0ba2b1a6bbf04f5b281454ab18313359151f58b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c65d9bcd2b757bf0a3e2d8b25b51b6a50b239e589efba142eb3c1c7539d42ac88c311361aa934f6ecf5be06c18da53c4e3c138dda801f0c89330da7c030a745
|
7
|
+
data.tar.gz: 10169aa8520c4d2dc4ddc92e419b77b745688c14bc08214770f9da25ed35b66d66655db37ef32daa7967119514ad3cacb618d06be5bd3c69df45e2ed435e9fb1
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## [0.1.6] - 2024-03-31
|
2
|
+
|
3
|
+
- enhance global perf by remove useless and heavy error handling
|
4
|
+
|
5
|
+
## [0.1.5] - 2024-03-31
|
6
|
+
|
7
|
+
- enhance performance of #each_byte (4 seconds faster on average)
|
8
|
+
|
1
9
|
## [0.1.4] - 2024-03-31
|
2
10
|
|
3
11
|
- more refactoring of Bitary class
|
data/lib/bitary/bitwarr.rb
CHANGED
@@ -2,132 +2,78 @@
|
|
2
2
|
|
3
3
|
class Bitary
|
4
4
|
class Bitwarr
|
5
|
-
attr_reader :bpi
|
5
|
+
attr_reader :bpi, :bitsize
|
6
6
|
|
7
7
|
def initialize(initial_data, bpi: Bitary::LONG)
|
8
|
-
|
9
|
-
|
8
|
+
@bitsize = init_bitsize(initial_data, bpi)
|
9
|
+
@array = init_array(initial_data, @bitsize, bpi)
|
10
|
+
@bpi = init_bpi(initial_data, bpi)
|
10
11
|
|
11
|
-
|
12
|
-
@bitsize = init_bitsize(initial_data)
|
13
|
-
@array = init_array(initial_data)
|
12
|
+
self.bpi = bpi
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def
|
21
|
-
@array.respond_to?(method, include_all) || super
|
22
|
-
end
|
23
|
-
|
24
|
-
def bitsize(bit_index = nil)
|
25
|
-
if bit_index.nil?
|
26
|
-
@bitsize
|
27
|
-
else
|
28
|
-
check_bit_index(bit_index)
|
29
|
-
|
30
|
-
last_index = @array.length - 1
|
31
|
-
if item_index(bit_index) == last_index
|
32
|
-
@bitsize - (last_index * @bpi)
|
33
|
-
else
|
34
|
-
@bpi
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def [](bit_index)
|
40
|
-
@array[item_index(bit_index)]
|
41
|
-
end
|
15
|
+
def [](bit_index) = @array[item_index(bit_index)]
|
16
|
+
def bit_at(index) = operate_bit_at(:get, index)
|
17
|
+
def bit_at!(index) = operate_bit_at!(:set, index)
|
18
|
+
def unbit_at!(index) = operate_bit_at!(:unset, index)
|
19
|
+
def to_s = @array.map { |item| to_binstr(item) }.join(' ')
|
42
20
|
|
43
21
|
def []=(bit_index, value)
|
44
|
-
raise ArgumentError unless value.is_a?(Integer)
|
45
|
-
|
46
22
|
@array[item_index(bit_index)] = value
|
47
23
|
end
|
48
24
|
|
49
|
-
def
|
50
|
-
check_bit_index(bit_index)
|
51
|
-
|
52
|
-
bit_index % @bpi
|
53
|
-
end
|
54
|
-
|
55
|
-
def item_index(bit_index)
|
56
|
-
check_bit_index(bit_index)
|
57
|
-
|
58
|
-
bit_index / @bpi
|
59
|
-
end
|
60
|
-
|
61
|
-
def bit_at(index)
|
62
|
-
operate_bit_at(:get, index)
|
63
|
-
end
|
64
|
-
|
65
|
-
def bit_at!(index)
|
66
|
-
operate_bit_at!(:set, index)
|
67
|
-
end
|
68
|
-
|
69
|
-
def unbit_at!(index)
|
70
|
-
operate_bit_at!(:unset, index)
|
71
|
-
end
|
72
|
-
|
73
|
-
def each_byte
|
25
|
+
def each_byte(&proc)
|
74
26
|
@array.each do |item|
|
75
|
-
(
|
76
|
-
byte = (item >> (@bpi - (Bitary::BYTE * (i + 1))))
|
77
|
-
yield byte
|
78
|
-
end
|
27
|
+
explode_item(item, Bitary::BYTE, @bpi, &proc)
|
79
28
|
end
|
80
29
|
end
|
81
30
|
|
82
|
-
def to_s
|
83
|
-
@array.map { |item| format("%0#{@bpi}d", item.to_s(2)) }.join(' ')
|
84
|
-
end
|
85
|
-
|
86
31
|
def bpi=(value)
|
87
|
-
|
32
|
+
return if value == @bpi
|
88
33
|
|
89
34
|
update_items_size!(value)
|
90
|
-
|
91
35
|
@bpi = value
|
92
36
|
end
|
93
37
|
|
38
|
+
def method_missing(method, *, &)
|
39
|
+
@array.respond_to?(method) ? @array.send(method, *, &) : super
|
40
|
+
end
|
41
|
+
|
42
|
+
def respond_to_missing?(method, include_all = false)
|
43
|
+
@array.respond_to?(method, include_all) || super
|
44
|
+
end
|
45
|
+
|
94
46
|
private
|
95
47
|
|
96
|
-
def
|
97
|
-
initial_data.is_a?(Array) ?
|
48
|
+
def init_bpi(initial_data, bpi)
|
49
|
+
initial_data.is_a?(Array) ? Bitary::BYTE : bpi
|
50
|
+
end
|
51
|
+
|
52
|
+
def init_bitsize(initial_data, bpi)
|
53
|
+
initial_data.is_a?(Array) ? bpi * initial_data.length : initial_data
|
98
54
|
end
|
99
55
|
|
100
|
-
def init_array(initial_data)
|
56
|
+
def init_array(initial_data, bitsize, bpi)
|
101
57
|
if initial_data.is_a?(Array)
|
102
58
|
initial_data.clone
|
103
59
|
else
|
104
|
-
[0] * (
|
60
|
+
[0] * (bitsize / bpi.to_f).ceil
|
105
61
|
end
|
106
62
|
end
|
107
63
|
|
108
|
-
def
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
def check_bit_index(bit_index)
|
113
|
-
raise ArgumentError unless bit_index.is_a?(Integer)
|
114
|
-
raise IndexError if bit_index.negative? || bit_index >= @bitsize
|
64
|
+
def item_index(bit_index)
|
65
|
+
bit_index / @bpi
|
115
66
|
end
|
116
67
|
|
117
|
-
def
|
118
|
-
|
119
|
-
Bitary::BYTE,
|
120
|
-
Bitary::SHORT,
|
121
|
-
Bitary::INT,
|
122
|
-
Bitary::LONG
|
123
|
-
].include?(bpi)
|
68
|
+
def to_binstr(item)
|
69
|
+
format("%0#{@bpi}d", item.to_s(2))
|
124
70
|
end
|
125
71
|
|
126
72
|
def operate_bit_at(operation, index)
|
127
73
|
Factory
|
128
74
|
.make("Handler::#{operation.capitalize}", self[index])
|
129
75
|
.execute(
|
130
|
-
index:
|
76
|
+
index: index % @bpi,
|
131
77
|
size: @bpi
|
132
78
|
)
|
133
79
|
end
|
@@ -137,29 +83,34 @@ class Bitary
|
|
137
83
|
end
|
138
84
|
|
139
85
|
def update_items_size!(value)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
86
|
+
value > @bpi ? increase_items_size!(value) : decrease_items_size!(value)
|
87
|
+
end
|
88
|
+
|
89
|
+
def append_bits(item, bpi, addend)
|
90
|
+
Factory.make('Handler::Append', item).execute(
|
91
|
+
offset: bpi,
|
92
|
+
value: addend
|
93
|
+
)
|
145
94
|
end
|
146
95
|
|
147
96
|
def increase_items_size(array, new_size, bpi)
|
148
97
|
processed_bits = 0
|
149
|
-
array.each_with_object([0]) do |
|
150
|
-
|
151
|
-
if processed_bits >= new_size
|
152
|
-
offset = 0
|
98
|
+
res = array.each_with_object([0]) do |item, acc|
|
99
|
+
if processed_bits == new_size
|
153
100
|
acc << 0
|
154
101
|
processed_bits = 0
|
155
102
|
end
|
156
103
|
|
157
|
-
acc[-1] =
|
158
|
-
offset:,
|
159
|
-
value:
|
160
|
-
)
|
104
|
+
acc[-1] = append_bits(acc[-1], bpi, item)
|
161
105
|
processed_bits += bpi
|
162
106
|
end
|
107
|
+
|
108
|
+
while processed_bits < new_size
|
109
|
+
res[-1] = append_bits(res[-1], bpi, 0)
|
110
|
+
processed_bits += bpi
|
111
|
+
end
|
112
|
+
|
113
|
+
res
|
163
114
|
end
|
164
115
|
|
165
116
|
def increase_items_size!(value)
|
@@ -168,7 +119,9 @@ class Bitary
|
|
168
119
|
|
169
120
|
def decrease_items_size(array, new_size, bpi)
|
170
121
|
array.each_with_object([]) do |item, acc|
|
171
|
-
|
122
|
+
explode_item(item, new_size, bpi) do |new_item|
|
123
|
+
acc << new_item
|
124
|
+
end
|
172
125
|
end
|
173
126
|
end
|
174
127
|
|
@@ -177,16 +130,10 @@ class Bitary
|
|
177
130
|
end
|
178
131
|
|
179
132
|
def explode_item(item, new_size, bpi)
|
180
|
-
res = []
|
181
|
-
offset = bpi
|
182
133
|
mask = (2**new_size) - 1
|
183
|
-
|
184
|
-
|
185
|
-
offset -= new_size
|
186
|
-
res << ((item >> offset) & mask)
|
134
|
+
(bpi / new_size).times do |i|
|
135
|
+
yield ((item >> (bpi - (new_size * (i + 1)))) & mask)
|
187
136
|
end
|
188
|
-
|
189
|
-
res
|
190
137
|
end
|
191
138
|
end
|
192
139
|
end
|
data/lib/bitary/decorator.rb
CHANGED
@@ -3,17 +3,6 @@
|
|
3
3
|
class Bitary
|
4
4
|
class Handler
|
5
5
|
class Append < Bitary::Handler
|
6
|
-
SPEC = {
|
7
|
-
offset: {
|
8
|
-
required: true,
|
9
|
-
type: Integer
|
10
|
-
},
|
11
|
-
value: {
|
12
|
-
required: true,
|
13
|
-
type: Integer
|
14
|
-
}
|
15
|
-
}.freeze
|
16
|
-
|
17
6
|
def execute(**kwargs)
|
18
7
|
(@value << kwargs[:offset]) | kwargs[:value]
|
19
8
|
end
|
data/lib/bitary/handler/get.rb
CHANGED
@@ -3,23 +3,6 @@
|
|
3
3
|
class Bitary
|
4
4
|
class Handler
|
5
5
|
class Get < Bitary::Handler
|
6
|
-
SPEC = {
|
7
|
-
index: {
|
8
|
-
required: true,
|
9
|
-
type: Integer,
|
10
|
-
predicate: {
|
11
|
-
callback: lambda do |**kwargs|
|
12
|
-
kwargs[:index] >= 0 && kwargs[:index] < kwargs[:size]
|
13
|
-
end,
|
14
|
-
error: IndexError
|
15
|
-
}
|
16
|
-
},
|
17
|
-
size: {
|
18
|
-
required: true,
|
19
|
-
type: Integer
|
20
|
-
}
|
21
|
-
}.freeze
|
22
|
-
|
23
6
|
def execute(**kwargs)
|
24
7
|
(@value >> (kwargs[:size] - kwargs[:index] - 1)) & 0x1
|
25
8
|
end
|
data/lib/bitary/handler/set.rb
CHANGED
@@ -3,23 +3,6 @@
|
|
3
3
|
class Bitary
|
4
4
|
class Handler
|
5
5
|
class Set < Bitary::Handler
|
6
|
-
SPEC = {
|
7
|
-
index: {
|
8
|
-
required: true,
|
9
|
-
type: Integer,
|
10
|
-
predicate: {
|
11
|
-
callback: lambda do |**kwargs|
|
12
|
-
kwargs[:index] >= 0 && kwargs[:index] < kwargs[:size]
|
13
|
-
end,
|
14
|
-
error: IndexError
|
15
|
-
}
|
16
|
-
},
|
17
|
-
size: {
|
18
|
-
required: true,
|
19
|
-
type: Integer
|
20
|
-
}
|
21
|
-
}.freeze
|
22
|
-
|
23
6
|
def execute(**kwargs)
|
24
7
|
@value | (2**(kwargs[:size] - kwargs[:index] - 1))
|
25
8
|
end
|
data/lib/bitary/handler/unset.rb
CHANGED
@@ -3,28 +3,10 @@
|
|
3
3
|
class Bitary
|
4
4
|
class Handler
|
5
5
|
class Unset < Bitary::Handler
|
6
|
-
SPEC = {
|
7
|
-
index: {
|
8
|
-
required: true,
|
9
|
-
type: Integer,
|
10
|
-
predicate: {
|
11
|
-
callback: lambda do |**kwargs|
|
12
|
-
kwargs[:index] >= 0 && kwargs[:index] < kwargs[:size]
|
13
|
-
end,
|
14
|
-
error: IndexError
|
15
|
-
}
|
16
|
-
},
|
17
|
-
size: {
|
18
|
-
required: true,
|
19
|
-
type: Integer
|
20
|
-
}
|
21
|
-
}.freeze
|
22
|
-
|
23
6
|
def execute(**kwargs)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@value & mask
|
7
|
+
size = kwargs[:size]
|
8
|
+
index = kwargs[:index]
|
9
|
+
@value & ((2**size) - 1 - (2**(size - index - 1)))
|
28
10
|
end
|
29
11
|
end
|
30
12
|
end
|
data/lib/bitary/handler.rb
CHANGED
@@ -7,20 +7,9 @@ require_relative 'handler/append'
|
|
7
7
|
|
8
8
|
class Bitary
|
9
9
|
class Handler
|
10
|
-
SPEC = {}.freeze
|
11
|
-
|
12
10
|
attr_reader :value
|
13
11
|
|
14
|
-
def self.new(*arg, **kwargs)
|
15
|
-
Decorator::SingleMethod::KwargsValidator.new(
|
16
|
-
super,
|
17
|
-
{ execute: self::SPEC }
|
18
|
-
)
|
19
|
-
end
|
20
|
-
|
21
12
|
def initialize(value)
|
22
|
-
raise ArgumentError unless value.is_a?(Integer)
|
23
|
-
|
24
13
|
@value = value
|
25
14
|
end
|
26
15
|
|
data/lib/bitary/version.rb
CHANGED
data/lib/bitary.rb
CHANGED
@@ -12,17 +12,24 @@ class Bitary
|
|
12
12
|
include Size
|
13
13
|
|
14
14
|
def initialize(initial_data, bpi: LONG)
|
15
|
-
|
15
|
+
check_initial_data(initial_data)
|
16
|
+
check_bpi(bpi)
|
17
|
+
|
18
|
+
@bitwarr = Factory.make('Bitwarr', initial_data, bpi:)
|
16
19
|
end
|
17
20
|
|
18
21
|
def [](index)
|
19
|
-
|
22
|
+
check_bit_index(index)
|
23
|
+
|
24
|
+
@bitwarr.bit_at(index)
|
20
25
|
end
|
21
26
|
|
22
27
|
def []=(index, value)
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
check_bit_index(index)
|
29
|
+
|
30
|
+
case Factory.make('Mapper::ObjToBit').map(value)
|
31
|
+
when 0 then @bitwarr.unbit_at!(index)
|
32
|
+
else @bitwarr.bit_at!(index)
|
26
33
|
end
|
27
34
|
end
|
28
35
|
|
@@ -35,27 +42,44 @@ class Bitary
|
|
35
42
|
end
|
36
43
|
|
37
44
|
def each_byte(&)
|
38
|
-
@
|
45
|
+
@bitwarr.each_byte(&)
|
39
46
|
end
|
40
47
|
|
41
48
|
def to_a
|
42
|
-
@
|
49
|
+
@bitwarr.to_a
|
43
50
|
end
|
44
51
|
|
45
52
|
def to_s
|
46
|
-
@
|
53
|
+
@bitwarr.to_s
|
47
54
|
end
|
48
55
|
|
49
56
|
def bpi=(value)
|
50
|
-
|
57
|
+
check_bpi(value)
|
58
|
+
|
59
|
+
@bitwarr.bpi = value
|
51
60
|
end
|
52
61
|
|
53
62
|
def size
|
54
|
-
@
|
63
|
+
@bitwarr.bitsize
|
55
64
|
end
|
56
65
|
|
57
66
|
def bpi
|
58
|
-
@
|
67
|
+
@bitwarr.bpi
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def check_initial_data(initial_data)
|
73
|
+
raise ArgumentError unless [Array, Integer].include?(initial_data.class)
|
74
|
+
end
|
75
|
+
|
76
|
+
def check_bpi(bpi)
|
77
|
+
raise ArgumentError unless [BYTE, SHORT, INT, LONG].include?(bpi)
|
78
|
+
end
|
79
|
+
|
80
|
+
def check_bit_index(bit_index)
|
81
|
+
raise ArgumentError unless bit_index.is_a?(Integer)
|
82
|
+
raise IndexError if bit_index.negative? || bit_index >= @bitwarr.bitsize
|
59
83
|
end
|
60
84
|
|
61
85
|
alias at []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maximilien Ballesteros
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby-based implementation of the bit array data structure
|
14
14
|
email:
|
@@ -26,10 +26,8 @@ files:
|
|
26
26
|
- lib/bitary.rb
|
27
27
|
- lib/bitary/bitwarr.rb
|
28
28
|
- lib/bitary/decorator.rb
|
29
|
-
- lib/bitary/decorator/kwargs_validator.rb
|
30
29
|
- lib/bitary/decorator/single_method.rb
|
31
30
|
- lib/bitary/decorator/single_method/non_nil_enforcer.rb
|
32
|
-
- lib/bitary/decorator/single_method/truthy_enforcer.rb
|
33
31
|
- lib/bitary/factory.rb
|
34
32
|
- lib/bitary/handler.rb
|
35
33
|
- lib/bitary/handler/append.rb
|
@@ -1,174 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Bitary
|
4
|
-
class Decorator
|
5
|
-
class KwargsValidator < Bitary::Decorator
|
6
|
-
SPEC_KEYS = %i[required default type predicate].freeze
|
7
|
-
|
8
|
-
def initialize(wrappee, spec)
|
9
|
-
super(wrappee) { |method| spec.key?(method) }
|
10
|
-
@spec = check_spec(@wrappee, spec)
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
def precall(method, *, **)
|
16
|
-
super(method, *, **check_kwargs(@spec, method, **))
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def check_spec(wrappee, spec)
|
22
|
-
raise ArgumentError unless spec.is_a?(Hash)
|
23
|
-
|
24
|
-
spec.each do |method, method_spec|
|
25
|
-
check_spec_method(wrappee, method)
|
26
|
-
check_spec_method_value(method_spec)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def check_kwargs(spec, method, **kwargs)
|
31
|
-
check_unexpected_user_kwargs(kwargs, spec[method])
|
32
|
-
check_kwargs_against_spec(kwargs, spec[method])
|
33
|
-
end
|
34
|
-
|
35
|
-
def check_spec_method(wrappee, method)
|
36
|
-
raise ArgumentError unless wrappee.respond_to?(method)
|
37
|
-
end
|
38
|
-
|
39
|
-
def check_spec_method_value(method_spec)
|
40
|
-
raise ArgumentError unless method_spec.is_a?(Hash)
|
41
|
-
|
42
|
-
method_spec.each_value do |arg_spec|
|
43
|
-
raise ArgumentError unless arg_spec.is_a?(Hash)
|
44
|
-
|
45
|
-
check_arg_spec(arg_spec)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def check_arg_spec(arg_spec)
|
50
|
-
raise ArgumentError unless arg_spec.keys.all? do |spec_key|
|
51
|
-
SPEC_KEYS.include?(spec_key)
|
52
|
-
end
|
53
|
-
|
54
|
-
arg_spec.each do |spec_key, spec_value|
|
55
|
-
check_arg_spec_entry(spec_key, spec_value)
|
56
|
-
end
|
57
|
-
|
58
|
-
return unless arg_spec.key?(:required) && arg_spec[:required]
|
59
|
-
raise ArgumentError if arg_spec.key?(:default)
|
60
|
-
end
|
61
|
-
|
62
|
-
def check_arg_spec_entry(key, value)
|
63
|
-
case key
|
64
|
-
when :required then check_required(value)
|
65
|
-
when :default then check_default(value)
|
66
|
-
when :type then check_type(value)
|
67
|
-
when :predicate then check_predicate(value)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def check_required(value)
|
72
|
-
raise ArgumentError unless [true, false].include?(value)
|
73
|
-
end
|
74
|
-
|
75
|
-
def check_default(value)
|
76
|
-
# NOTHING TODO
|
77
|
-
end
|
78
|
-
|
79
|
-
def check_type(value)
|
80
|
-
raise ArgumentError unless value.is_a?(Class)
|
81
|
-
end
|
82
|
-
|
83
|
-
def check_predicate(value)
|
84
|
-
raise ArgumentError unless value.is_a?(Hash)
|
85
|
-
|
86
|
-
check_predicate_keys(value)
|
87
|
-
check_predicate_values(value)
|
88
|
-
end
|
89
|
-
|
90
|
-
def check_predicate_keys(value)
|
91
|
-
available_keys = %i[callback error]
|
92
|
-
|
93
|
-
raise ArgumentError unless value.keys.all? do |key|
|
94
|
-
available_keys.include?(key)
|
95
|
-
end
|
96
|
-
|
97
|
-
raise KeyError unless value.key?(:callback) && value.key?(:error)
|
98
|
-
end
|
99
|
-
|
100
|
-
def check_predicate_values(value)
|
101
|
-
raise ArgumentError unless value[:callback].is_a?(Proc)
|
102
|
-
raise ArgumentError unless value[:error].is_a?(Class)
|
103
|
-
raise ArgumentError unless value[:error] < Exception
|
104
|
-
end
|
105
|
-
|
106
|
-
def check_unexpected_user_kwargs(user_kwargs, method_spec)
|
107
|
-
raise ArgumentError unless user_kwargs.keys.all? do |key|
|
108
|
-
method_spec.include?(key)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def check_kwargs_against_spec(user_kwargs, method_spec)
|
113
|
-
predicates = []
|
114
|
-
|
115
|
-
parsed_kwargs = method_spec.reduce({}) do |acc, entry|
|
116
|
-
kwarg_name, kwarg_spec = entry
|
117
|
-
loaded_spec = load_spec(kwarg_spec)
|
118
|
-
|
119
|
-
validate_required(user_kwargs, loaded_spec, kwarg_name)
|
120
|
-
validate_type(user_kwargs, loaded_spec, kwarg_name)
|
121
|
-
predicates << loaded_spec[:predicate]
|
122
|
-
|
123
|
-
acc.merge(
|
124
|
-
kwarg_name => compute_value(user_kwargs, loaded_spec, kwarg_name)
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
128
|
-
predicates.each do |predicate|
|
129
|
-
validate_predicate(parsed_kwargs, predicate)
|
130
|
-
end
|
131
|
-
|
132
|
-
parsed_kwargs
|
133
|
-
end
|
134
|
-
|
135
|
-
def load_spec(kwarg_spec)
|
136
|
-
{
|
137
|
-
required: kwarg_spec[:required] || false,
|
138
|
-
default: kwarg_spec[:default],
|
139
|
-
type: kwarg_spec[:type] || Object,
|
140
|
-
predicate: kwarg_spec[:predicate] || {
|
141
|
-
callback: ->(_value) { true },
|
142
|
-
error: ArgumentError
|
143
|
-
}
|
144
|
-
}
|
145
|
-
end
|
146
|
-
|
147
|
-
def validate_required(user_kwargs, spec, expected_key)
|
148
|
-
return unless spec[:required]
|
149
|
-
|
150
|
-
raise KeyError unless user_kwargs.key?(expected_key)
|
151
|
-
end
|
152
|
-
|
153
|
-
def validate_type(user_kwargs, spec, expected_key)
|
154
|
-
return unless user_kwargs.key?(expected_key)
|
155
|
-
|
156
|
-
raise ArgumentError unless user_kwargs[expected_key].is_a?(spec[:type])
|
157
|
-
end
|
158
|
-
|
159
|
-
def validate_predicate(parsed_kwargs, predicate)
|
160
|
-
return if predicate[:callback].call(**parsed_kwargs)
|
161
|
-
|
162
|
-
raise predicate[:error]
|
163
|
-
end
|
164
|
-
|
165
|
-
def compute_value(user_kwargs, spec, expected_key)
|
166
|
-
if user_kwargs.key?(expected_key)
|
167
|
-
user_kwargs[expected_key]
|
168
|
-
else
|
169
|
-
spec[:default]
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Bitary
|
4
|
-
class Decorator
|
5
|
-
class SingleMethod < Bitary::Decorator
|
6
|
-
class TruthyEnforcer < Bitary::Decorator::SingleMethod
|
7
|
-
protected
|
8
|
-
|
9
|
-
def postcall(resp)
|
10
|
-
resp or raise TypeError
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|