ree_lib 1.0.69 → 1.0.70

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: c746828c8b09f58c0406659649ef01ba7b7300f4b1f35f808f8e1f58a0dc4165
4
- data.tar.gz: c03ddd00be42dbbe2ee2e2660a105a84912d19ccb5251fd882bd88d04e5bd781
3
+ metadata.gz: 40e7e6a91b65f1bab58b667f1eebf153ac5fd1c85852e189af8d3a6d2ea8b163
4
+ data.tar.gz: 5ac2658d206e2aa8963fd90ed4ca4ef071b701a0d02414d571dcc95df825a88e
5
5
  SHA512:
6
- metadata.gz: 5fa6ca950b18d4e6678610f8dd1b1d3c239090e18d7c914be33643e75d846332e041109d8cb2f6d301398e9eafeeb6897320bfac688c2defb427bc2bec6a4e5c
7
- data.tar.gz: 13405b30d0b4be4aba5e579f8bab5a410af29fe820a5aca37502ea6a7d356a5d5fdad315214fa70b8581927c7ee712607a101b191ec2d9fd383a4b4e1989f8a8
6
+ metadata.gz: 221b1612a9ddc52b73f6cd34a1f1228009a3459646d0f129281d5c4ae16557e1044359cb13e44085bf1e727ae07ce3be7cfae9e1728fae8260ed42f888a52010
7
+ data.tar.gz: e296d1413246f6813ec865ae1395eec11f71f2066d755d815ccac8a260278f122c20e6ca0c680204245a693aa9668dfaab46c0187e25e51288be6c4d523c5e7a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.69)
4
+ ree_lib (1.0.70)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -4,10 +4,10 @@ module ReeEnum::Contractable
4
4
  include Ree::Contracts::Truncatable
5
5
 
6
6
  def valid?(value)
7
- value.is_a?(ReeEnum::Value) && value.enum_name == self.enum_name && all.include?(value)
7
+ value.is_a?(ReeEnum::Value) && value.enum_name == get_enum_name && get_values.each.include?(value)
8
8
  end
9
9
 
10
10
  def message(value, name, lvl = 1)
11
- return "expected one of #{self.name}, got #{value.class} => #{truncate(value.inspect)}"
11
+ "expected one of #{self.name}, got #{value.class} => #{truncate(value.inspect)}"
12
12
  end
13
13
  end
@@ -52,28 +52,17 @@ module ReeEnum
52
52
  ] => ReeEnum::Value
53
53
  ).throws(ReeMapper::CoercionError)
54
54
  def cast(value, name:, role: nil)
55
- if value.is_a?(String)
56
- enum_val = @enum.values.all.detect { |v| v.to_s == value }
57
-
58
- if !enum_val
59
- raise ReeMapper::CoercionError, "`#{name}` should be one of #{@enum.values.all.map(&:to_s).inspect}"
60
- end
61
-
62
- enum_val
63
- elsif value.is_a?(Integer)
64
- enum_val = @enum.values.all.detect { |v| v.to_i == value }
65
-
66
- if !enum_val
67
- raise ReeMapper::CoercionError, "`#{name}` should be one of #{@enum.values.all.map(&:to_s).inspect}"
68
- end
69
-
70
- enum_val
71
- else
72
- enum_val = @enum.values.all.detect { |v| v == value }
73
- return enum_val if enum_val
55
+ enum_value = if value.is_a?(String)
56
+ @enum.get_values.by_value(value)
57
+ elsif value.is_a?(ReeEnum::Value)
58
+ @enum.get_values.each.find { _1 == value }
59
+ end
74
60
 
75
- raise ReeMapper::CoercionError, "`#{name}` should be one of #{@enum.values.all.map(&:to_s).inspect}"
61
+ if enum_value.nil?
62
+ raise ReeMapper::CoercionError, "`#{name}` should be one of #{enum_inspection}"
76
63
  end
64
+
65
+ enum_value
77
66
  end
78
67
 
79
68
  contract(
@@ -81,21 +70,38 @@ module ReeEnum
81
70
  Kwargs[
82
71
  name: String,
83
72
  role: Nilor[Symbol, ArrayOf[Symbol]]
84
- ] => Integer
73
+ ] => Or[Integer, String]
85
74
  )
86
75
  def db_dump(value, name:, role: nil)
87
- value.to_i
76
+ value.mapped_value
88
77
  end
89
78
 
90
79
  contract(
91
- Integer,
80
+ Or[Integer, String],
92
81
  Kwargs[
93
82
  name: String,
94
83
  role: Nilor[Symbol, ArrayOf[Symbol]]
95
84
  ] => ReeEnum::Value
96
- ).throws(ReeMapper::TypeError)
85
+ ).throws(ReeMapper::CoercionError)
97
86
  def db_load(value, name:, role: nil)
98
- cast(value, name: name, role: role)
87
+ enum_val = @enum.get_values.by_mapped_value(value)
88
+
89
+ if !enum_val
90
+ raise ReeMapper::CoercionError, "`#{name}` should be one of #{enum_inspection}"
91
+ end
92
+
93
+ enum_val
94
+ end
95
+
96
+ private
97
+
98
+ def enum_inspection
99
+ @enum_inspect ||= truncate(@enum.get_values.each.map(&:to_s).inspect)
100
+ end
101
+
102
+ def truncate(str, limit = 180)
103
+ return str if str.length <= limit
104
+ "#{str[0..limit]}..."
99
105
  end
100
106
  end
101
107
 
@@ -113,7 +119,7 @@ module ReeEnum
113
119
  ->(*) {
114
120
  {
115
121
  type: 'string',
116
- enum: values.all.map(&:to_s)
122
+ enum: get_values.each.map(&:to_s)
117
123
  }
118
124
  }
119
125
  )
@@ -128,7 +134,7 @@ module ReeEnum
128
134
  )
129
135
 
130
136
  mapper_factory.register_type(
131
- self.enum_name, type_for_mapper
137
+ self.get_enum_name, type_for_mapper
132
138
  )
133
139
  end
134
140
  end
@@ -5,20 +5,6 @@ require_relative 'values'
5
5
  require_relative 'contractable'
6
6
 
7
7
  module ReeEnum::Enumerable
8
- module CommonMethods
9
- def by_value(value)
10
- values.by_value(value)
11
- end
12
-
13
- def by_number(number)
14
- values.by_number(number)
15
- end
16
-
17
- def all
18
- values.all
19
- end
20
- end
21
-
22
8
  def self.included(base)
23
9
  base.extend(ClassMethods)
24
10
  end
@@ -26,43 +12,45 @@ module ReeEnum::Enumerable
26
12
  module ClassMethods
27
13
  include ReeEnum::Contractable
28
14
 
15
+ RESTRICTED_METHODS = [
16
+ :setup_enum, :get_values, :get_enum_name,
17
+ :val, :self, :class, :alias
18
+ ].freeze
19
+
29
20
  def setup_enum(enum_name)
30
21
  @values ||= ReeEnum::Values.new(self, enum_name)
31
22
  end
32
23
 
33
- def values
24
+ def get_values
34
25
  @values
35
26
  end
36
27
 
37
- def enum_name
38
- return if !@values
39
- @values.enum_name
28
+ def get_enum_name
29
+ @values&.enum_name
40
30
  end
41
31
 
42
- include CommonMethods
32
+ def val(value, mapped_value = value.to_s, method: value.to_sym)
33
+ value = value.to_s
43
34
 
44
- def val(value, number, label = nil)
45
- if value == :new
46
- raise ArgumentError.new(":new is not allowed as enum value")
35
+ if RESTRICTED_METHODS.include?(method)
36
+ raise ArgumentError.new("#{method.inspect} is not allowed as enum method")
47
37
  end
48
-
49
- enum_value = values.add(value, number: number, label: label)
50
38
 
51
- define_method "#{enum_value.value}" do
52
- by_value(enum_value.value)
39
+ enum_value = @values.add(value, mapped_value, method)
40
+
41
+ define_method(enum_value.method) do
42
+ get_values.by_value(enum_value.value)
53
43
  end
54
44
 
55
- define_singleton_method "#{enum_value.value}" do
56
- by_value(enum_value.value)
45
+ define_singleton_method(enum_value.method) do
46
+ get_values.by_value(enum_value.value)
57
47
  end
58
48
 
59
49
  enum_value
60
50
  end
61
51
  end
62
52
 
63
- def values
64
- self.class.values
53
+ def get_values
54
+ self.class.get_values
65
55
  end
66
-
67
- include CommonMethods
68
56
  end
@@ -1,60 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ReeEnum::Value
4
- attr_reader :enum_class, :enum_name, :value, :label, :number
4
+ attr_reader :enum_class, :enum_name, :value, :method, :mapped_value
5
5
 
6
- contract(Class, Symbol, Symbol, Integer, Nilor[String] => Any)
7
- def initialize(enum_class, enum_name, value, number, label)
6
+ contract(Class, Symbol, String, Or[Integer, String], Symbol => Any)
7
+ def initialize(enum_class, enum_name, value, mapped_value, method)
8
8
  @enum_class = enum_class
9
9
  @enum_name = enum_name
10
10
  @value = value
11
- @label = label
12
- @number = number
11
+ @method = method
12
+ @mapped_value = mapped_value
13
13
  end
14
14
 
15
15
  def to_s
16
- @value.to_s
16
+ value
17
17
  end
18
18
 
19
- def to_sym
20
- @value
21
- end
22
-
23
- def to_i
24
- @number
19
+ def to_sql
20
+ mapped_value
25
21
  end
26
22
 
27
23
  def as_json(*args)
28
24
  to_s
29
25
  end
30
26
 
31
- def label
32
- @label
33
- end
34
-
35
- contract(Or[ReeEnum::Value, Symbol, Integer, Any] => Bool)
27
+ contract(Or[ReeEnum::Value, String, Symbol, Integer, Any] => Bool)
36
28
  def ==(compare)
37
29
  if compare.is_a?(self.class)
38
- @value == compare.value
30
+ value == compare.value
31
+ elsif compare.is_a?(Symbol)
32
+ value == compare.to_s
33
+ elsif compare.is_a?(String)
34
+ value == compare || mapped_value == compare
35
+ elsif compare.is_a?(Integer)
36
+ mapped_value == compare
39
37
  else
40
- @value == compare || @number == compare
38
+ false
41
39
  end
42
40
  end
43
41
 
44
- contract(Or[ReeEnum::Value, String, Integer] => Bool)
45
- def <=>(other)
46
- if other.is_a?(self.class)
47
- @number <=> other.number
48
- elsif other.is_a?(Symbol)
49
- @value == other
50
- elsif other.is_a?(Integer)
51
- @number == other
52
- else
53
- raise ArgumentError.new("unable to compare ReeEnum::Value with other classes")
54
- end
55
- end
56
-
57
42
  def inspect
58
- "#{enum_class.name}##{@value.to_s}"
43
+ "#{enum_class.name}##{value}"
59
44
  end
60
45
  end
@@ -6,41 +6,67 @@ class ReeEnum::Values
6
6
  def initialize(klass, enum_name)
7
7
  @klass = klass
8
8
  @enum_name = enum_name
9
- @collection = {}
9
+ @collection = []
10
+ @collection_by_value = {}
11
+ @collection_by_mapped_value = {}
10
12
  end
11
13
 
12
- def all
13
- @collection.values.sort_by(&:number)
14
+ def to_a
15
+ @collection
14
16
  end
15
17
 
16
- contract(Symbol => ReeEnum::Value).throws(ArgumentError)
18
+ def each(&)
19
+ @collection.each(&)
20
+ end
21
+
22
+ contract(Or[Symbol, String] => Nilor[ReeEnum::Value])
17
23
  def by_value(value)
18
- type = @collection.values.detect {|c| c.value == value}
19
- type || (raise ArgumentError.new("constant for value #{value.inspect} is not found in #{self.inspect}"))
24
+ @collection_by_value[value.to_s]
25
+ end
26
+
27
+ contract(Or[Symbol, String] => ReeEnum::Value).throws(ArgumentError)
28
+ def by_value!(value)
29
+ by_value(value) ||
30
+ (raise ArgumentError.new("constant for value #{value.inspect} is not found in #{self.inspect}"))
31
+ end
32
+
33
+ contract(Or[Integer, String] => Nilor[ReeEnum::Value])
34
+ def by_mapped_value(mapped_value)
35
+ @collection_by_mapped_value[mapped_value]
20
36
  end
21
37
 
22
- contract(Integer => ReeEnum::Value).throws(ArgumentError)
23
- def by_number(number)
24
- type = @collection.values.detect {|c| c.number == number}
25
- type || (raise ArgumentError.new("constant for value #{number.inspect} is not found in #{self.inspect}"))
38
+ contract(Or[Integer, String] => ReeEnum::Value).throws(ArgumentError)
39
+ def by_mapped_value!(mapped_value)
40
+ by_mapped_value(mapped_value) ||
41
+ (raise ArgumentError.new("constant for value #{mapped_value.inspect} is not found in #{self.inspect}"))
26
42
  end
27
43
 
28
44
  def inspect
29
- @collection.values.map(&:inspect).inspect
45
+ @collection.map(&:inspect).inspect
30
46
  end
31
47
 
32
- contract(Symbol, Kwargs[number: Integer, label: Nilor[String]] => ReeEnum::Value)
33
- def add(value, number:, label: nil)
34
- if @collection.has_key?(value)
48
+ contract(String, Or[Integer, String], Symbol => ReeEnum::Value)
49
+ def add(value, mapped_value, method)
50
+ if @collection.any? { _1.method == method }
51
+ raise ArgumentError, "#{@klass}: method #{method.inspect} was already added"
52
+ end
53
+
54
+ if @collection_by_value.key?(value)
35
55
  raise ArgumentError, "#{@klass}: value #{value.inspect} was already added"
36
56
  end
37
57
 
38
- if @collection.values.any? {|v| v.number == number}
39
- raise ArgumentError, "number for #{value.inspect} was already added"
58
+ if @collection_by_mapped_value.key?(mapped_value)
59
+ raise ArgumentError, "#{@klass}: mapped_value(#{mapped_value.inspect}) for #{value.inspect} was already added"
40
60
  end
41
61
 
42
- @collection[value] = ReeEnum::Value.new(
43
- @klass, @enum_name, value, number, label
62
+ enum_value = ReeEnum::Value.new(
63
+ @klass, @enum_name, value, mapped_value, method
44
64
  )
65
+
66
+ @collection << enum_value
67
+ @collection_by_value[value] = enum_value
68
+ @collection_by_mapped_value[mapped_value] = enum_value
69
+
70
+ enum_value
45
71
  end
46
72
  end
@@ -32,11 +32,20 @@ RSpec.describe ReeEnum::DSL do
32
32
 
33
33
  enum :types
34
34
 
35
- val :account, 0
35
+ val :account
36
36
 
37
37
  register_as_mapper_type
38
38
  end
39
39
 
40
+ class Reflexives
41
+ include ReeEnum::DSL
42
+
43
+ enum :reflexives
44
+
45
+ val :self, method: :myself
46
+ val :yourself
47
+ end
48
+
40
49
  class TestMapper
41
50
  include ReeMapper::DSL
42
51
 
@@ -75,11 +84,11 @@ RSpec.describe ReeEnum::DSL do
75
84
  expect(o.first).to eq(0)
76
85
  expect(o.second).to eq(:second)
77
86
  expect(o.second).to eq(1)
78
- expect(o.by_value(:first)).to eq(o.first)
79
- expect(o.by_value(:second)).to eq(o.second)
80
- expect(o.by_number(0)).to eq(o.first)
81
- expect(o.by_number(1)).to eq(o.second)
82
- expect(o.all).to eq([o.first, o.second])
87
+ expect(o.get_values.by_value(:first)).to eq(o.first)
88
+ expect(o.get_values.by_value(:second)).to eq(o.second)
89
+ expect(o.get_values.by_mapped_value(0)).to eq(o.first)
90
+ expect(o.get_values.by_mapped_value(1)).to eq(o.second)
91
+ expect(o.get_values.to_a).to eq([o.first, o.second])
83
92
  end
84
93
 
85
94
  expect {
@@ -146,18 +155,20 @@ RSpec.describe ReeEnum::DSL do
146
155
  ).to eq(
147
156
  {
148
157
  state: 0,
149
- type: 0
158
+ type: "account"
150
159
  }
151
160
  )
152
161
 
153
162
  dto = mapper.db_load({
154
163
  state: 0,
155
- type: 0,
164
+ type: "account",
156
165
  })
157
166
 
158
167
  expect(dto.state).to eq(TestReeEnum::States.first)
159
168
  expect(dto.state).to be_a(ReeEnum::Value)
160
169
  expect(dto.type).to eq(TestReeEnum::Types.account)
161
170
  expect(dto.type).to be_a(ReeEnum::Value)
171
+
172
+ expect(TestReeEnum::Reflexives.myself).to eq(:self)
162
173
  }
163
174
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.69"
4
+ VERSION = "1.0.70"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.69
4
+ version: 1.0.70
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-25 00:00:00.000000000 Z
11
+ date: 2023-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ree