meta_enum 1.0.0 → 2.0.0

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: 2613b743e3671c160c9e9402e181e49e300b4cbf0d89e8c42ed93299f8095a2f
4
- data.tar.gz: 4fb9192c6bcfb1096a6b605a574f975e00247662670b7cf51e2744a5867ff9ee
3
+ metadata.gz: ae4f6d4921c00b29216e850aa59e679b34c3eba7d5cf9d5ae9365a69c81b75aa
4
+ data.tar.gz: fc7018df488e1de04230d58a9d5b8181ea9686157dd0dee48fa48e97c180b20f
5
5
  SHA512:
6
- metadata.gz: 712fc2fddf6c361a890da5c24ce063556b0289d8bf437ccbc68b7051f501e7839a4926dafddc83bfbca055e8e206797c20117865586990f9e5b7c5eea75e0e26
7
- data.tar.gz: a43af11ac01bd954776e9ddb41d557c06707cb1941e8374c7bafcffbb4b1845968699528dd56b7e5a0733e32c085b581f7a5b9c540c0d20f66684b5cff40acca
6
+ metadata.gz: fdfd752d85a7df06677a109c44fb75589e2e494312a90860dc5b878cce6ab02de618154775c715251bf3e8bb3a5274d3e62d02cbdb71b7ed08f41247481998b1
7
+ data.tar.gz: a1ec0eb6670569f0bb5efa36b04c6406269b519d2313201c8c5d1fcc2be0eea641b714733f712392d05dd6e692d680f17e3aff37d243e91c3d8737321ad00cb4
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## 2.0.0 (January 27, 2018)
4
+
5
+ Support non-integer values.
6
+
7
+ This entailed some breaking changes:
8
+
9
+ * MetaEnum::Value renamed to MetaEnum::Element
10
+ * MetaEnum::MissingValue renamed to MetaEnum::MissingElement
11
+ * MetaEnum::Value#number renamed to value
12
+ * MetaEnum::Type#values renamed to elements
13
+ * MetaEnum::Type#values_by_name renamed to elements_by_name
14
+ * MetaEnum::Type#values_by_number renamed to elements_by_value
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- meta_enum (1.0.0)
4
+ meta_enum (2.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # MetaEnum
2
2
 
3
3
  MetaEnum is a library for handling enum types in Ruby. It makes it easy to
4
- convert between external numbers and internal names.
4
+ convert between external values and internal names.
5
5
 
6
6
  ## Installation
7
7
 
@@ -32,16 +32,16 @@ ColorType = MetaEnum::Type.new(red: 0, green: 1, blue: 2)
32
32
  Use the `[]` operator to lookup a value by name:
33
33
 
34
34
  ```ruby
35
- ColorType[:green] # => #<MetaEnum::Value: 1 => green}>
35
+ ColorType[:green] # => #<MetaEnum::Element: 1 => green}>
36
36
  ```
37
37
 
38
38
  Or lookup by number:
39
39
 
40
40
  ```ruby
41
- ColorType[1] # => #<MetaEnum::Value: 1 => green}>
41
+ ColorType[1] # => #<MetaEnum::Element: 1 => green}>
42
42
  ```
43
43
 
44
- Values can also be easily compared with numbers or names:
44
+ Elements can also be easily compared with values or names:
45
45
 
46
46
  ```ruby
47
47
  ColorType[:green] == 1 # => true
@@ -54,17 +54,17 @@ Missing names would almost always be a programming error, so that will raise an
54
54
  ColorType[:purple] # => raises: KeyError: key not found: :purple
55
55
  ```
56
56
 
57
- But missing numbers could mean that there are values defined externally we do not know about. So it is preferable not to raise an exception.
57
+ But missing values could mean that there are values defined externally we do not know about. So it is preferable not to raise an exception.
58
58
 
59
59
  ```ruby
60
- ColorType[42] # => #<MetaEnum::MissingValue: 42}>
60
+ ColorType[42] # => #<MetaEnum::MissingElement: 42}>
61
61
  ```
62
62
 
63
- Number and name can be retrieved from a `MetaEnum::Value`
63
+ Value and name can be retrieved from a `MetaEnum::Element`
64
64
 
65
65
  ```ruby
66
- v = ColorType[:red] # => #<MetaEnum::Value: 0 => red}>
67
- v.number # => 0
66
+ v = ColorType[:red] # => #<MetaEnum::Element: 0 => red}>
67
+ v.value # => 0
68
68
  v.name # => :red
69
69
  ```
70
70
 
@@ -75,6 +75,15 @@ AgeType = MetaEnum::Type.new(child: [0, "Less than 18"], adult: [1, "At least 18
75
75
  AgeType[:child].data # => "Less than 18"
76
76
  ```
77
77
 
78
+ Non-integer values can be enabled by passing a value_normalizer to `MetaEnum::Type.new`. For example, to use string values:
79
+
80
+ ```ruby
81
+ CardType = MetaEnum::Type.new({visa: "VS", mastercard: "MC", discover: "DS"}, value_normalizer: method(:String))
82
+ CardType[:visa] # => #<MetaEnum::Element: visa: "VS", data: nil>
83
+ CardType["VS"] # => #<MetaEnum::Element: visa: "VS", data: nil>
84
+ pry(main)> CardType["VS"].value # => "VS"
85
+ ```
86
+
78
87
  ## Development
79
88
 
80
89
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,9 +1,9 @@
1
1
  module MetaEnum
2
- class Value
3
- attr_reader :number, :name, :data, :type
2
+ class Element
3
+ attr_reader :value, :name, :data, :type
4
4
 
5
- def initialize(number, name, data, type)
6
- @number = Integer(number)
5
+ def initialize(value, name, data, type)
6
+ @value = value
7
7
  @name = name.to_sym
8
8
  @data = data
9
9
  @type = type
@@ -18,11 +18,10 @@ module MetaEnum
18
18
  false
19
19
  end
20
20
 
21
- def to_i; number; end
22
21
  def to_s; name.to_s; end
23
22
 
24
23
  def inspect
25
- "#<#{self.class}: #{name}: #{number}, data: #{data.inspect}>"
24
+ "#<#{self.class}: #{name}: #{value.inspect}, data: #{data.inspect}>"
26
25
  end
27
26
  end
28
27
  end
@@ -1,9 +1,9 @@
1
1
  module MetaEnum
2
- class MissingValue
3
- attr_reader :number, :type
2
+ class MissingElement
3
+ attr_reader :value, :type
4
4
 
5
- def initialize(number, type)
6
- @number = Integer(number)
5
+ def initialize(value, type)
6
+ @value = value
7
7
  @type = type
8
8
  freeze
9
9
  end
@@ -13,18 +13,17 @@ module MetaEnum
13
13
 
14
14
  def ==(other)
15
15
  other = type[other]
16
- number == other.number && type == other.type
16
+ value == other.value && type == other.type
17
17
 
18
18
  # type[] will raise for certain bad keys. Those are obviously not equal so return false.
19
19
  rescue ArgumentError, KeyError
20
20
  false
21
21
  end
22
22
 
23
- def to_i; number; end
24
23
  def to_s; name.to_s; end
25
24
 
26
25
  def inspect
27
- "#<#{self.class}: #{number}}>"
26
+ "#<#{self.class}: #{value.inspect}}>"
28
27
  end
29
28
  end
30
29
  end
@@ -1,75 +1,104 @@
1
1
  require 'set'
2
2
 
3
3
  module MetaEnum
4
+
5
+ # ValueNormalizationError is raised on when a value normalization fails. It wraps the underlying exception.
6
+ class ValueNormalizationError < StandardError
7
+ attr_reader :original_exception, :original_value
8
+
9
+ def initialize(original_exception, original_value)
10
+ @original_exception = original_exception
11
+ @original_value = original_value
12
+ end
13
+
14
+ def to_s
15
+ "original_exception: #{original_exception}, original_value: #{original_value}"
16
+ end
17
+ end
18
+
4
19
  class Type
5
- attr_reader :values, :values_by_number, :values_by_name
20
+ attr_reader :elements, :elements_by_value, :elements_by_name
6
21
 
7
- # Initialize takes a single hash of name to number.
22
+ # Initialize takes a single hash of name to value.
8
23
  #
9
24
  # e.g. MetaEnum::Type.new(red: 0, green: 1, blue: 2)
10
25
  #
11
26
  # Additional data can also be associated with each value by passing an array
12
- # of [number, extra data]. This can be used for additional description or
27
+ # of [value, extra data]. This can be used for additional description or
13
28
  # any other reason.
14
29
  #
15
30
  # e.g. MetaEnum::Type.new(small: [0, "Less than 10], large: [1, "At least 10"]
16
- def initialize(values)
17
- @values_by_number = {}
18
- @values_by_name = {}
19
- @values = Set.new
31
+ #
32
+ # value_normalizer is a callable object that normalizes values. The default
33
+ # converts all values to integers. To allow string values use method(:String).
34
+ def initialize(
35
+ elements,
36
+ value_normalizer: method(:Integer)
37
+ )
38
+ @value_normalizer = value_normalizer
39
+ @elements_by_value = {}
40
+ @elements_by_name = {}
41
+ @elements = Set.new
20
42
 
21
- values.each do |name, number_and_data|
22
- number_and_data = Array(number_and_data)
23
- v = Value.new number_and_data[0], name, number_and_data[1], self
24
- raise ArgumentError, "duplicate number: #{v.number}" if @values_by_number.key? v.number
25
- raise ArgumentError, "duplicate name: #{v.name}" if @values_by_name.key? v.name
26
- @values_by_number[v.number] = v
27
- @values_by_name[v.name] = v
28
- @values.add(v)
43
+ elements.each do |name, value_and_data|
44
+ value_and_data = Array(value_and_data)
45
+ v = Element.new normalize_value(value_and_data[0]), name, value_and_data[1], self
46
+ raise ArgumentError, "duplicate value: #{v.value}" if @elements_by_value.key? v.value
47
+ raise ArgumentError, "duplicate name: #{v.name}" if @elements_by_name.key? v.name
48
+ @elements_by_value[v.value] = v
49
+ @elements_by_name[v.name] = v
50
+ @elements.add(v)
29
51
  end
30
52
 
31
- @values_by_number.freeze
32
- @values_by_name.freeze
33
- @values.freeze
53
+ @elements_by_value.freeze
54
+ @elements_by_name.freeze
55
+ @elements.freeze
34
56
  freeze
35
57
  end
36
58
 
37
- # [] is a "do what I mean" operator. It returns the Value from this type depending on the key.
59
+ # [] is a "do what I mean" operator. It returns the Element from this type depending on the key.
38
60
  #
39
- # When key is a symbol, it is considered the name of the Value to return.
61
+ # When key is a symbol, it is considered the name of the Element to return.
40
62
  # Since symbols are used from number, it is considered an error if the key is
41
63
  # not found and it raises an exception.
42
64
  #
43
65
  # When key can be converted to an integer by Integer(), then it is
44
- # considered the number of the Value to return. Retrieving by number is
66
+ # considered the number of the Element to return. Retrieving by number is
45
67
  # presumed to converting from external data where a missing value should not
46
- # be considered fatal. In this case it returns a MissingValue is with number
68
+ # be considered fatal. In this case it returns a MissingElement is with number
47
69
  # as the key. This allows a Type to only specify the values is needs while
48
70
  # passing through the others unmodified.
49
71
  #
50
- # Finally, when key is a MetaEnum::Value, it is simply returned (unless it
72
+ # Finally, when key is a MetaEnum::Element, it is simply returned (unless it
51
73
  # belongs to a different Type in which case an ArgumentError is raised).
52
74
  #
53
75
  # See #values_by_number and #values_by_name for non-fuzzy value selection.
54
76
  def [](key)
55
77
  case key
56
- when Value, MissingValue
78
+ when Element, MissingElement
57
79
  raise ArgumentError, "wrong type" unless key.type == self
58
80
  key
59
81
  when Symbol
60
- values_by_name.fetch(key)
82
+ elements_by_name.fetch(key)
61
83
  else
62
- key = Integer(key)
63
- values_by_number.fetch(key) { MissingValue.new key, self }
84
+ key = normalize_value(key)
85
+ elements_by_value.fetch(key) { MissingElement.new key, self }
64
86
  end
65
87
  end
66
88
 
67
89
  def inspect
68
- sprintf('#<%s: {%s}>', self.class, values.to_a.map { |v| "#{v.name}: #{v.number}"}.join(", "))
90
+ sprintf('#<%s: {%s}>', self.class, elements.to_a.map { |v| "#{v.name}: #{v.number}"}.join(", "))
69
91
  end
70
92
 
71
93
  def size
72
- values.size
94
+ elements.size
95
+ end
96
+
97
+ private
98
+ def normalize_value(value)
99
+ @value_normalizer.call(value)
100
+ rescue StandardError => e
101
+ raise ValueNormalizationError.new(e, value)
73
102
  end
74
103
  end
75
104
  end
@@ -1,3 +1,3 @@
1
1
  module MetaEnum
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/meta_enum.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  require "meta_enum/version"
2
2
  require 'meta_enum/type.rb'
3
- require 'meta_enum/value.rb'
4
- require 'meta_enum/missing_value.rb'
3
+ require 'meta_enum/element.rb'
4
+ require 'meta_enum/missing_element.rb'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meta_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Christensen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-26 00:00:00.000000000 Z
11
+ date: 2018-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
77
  - ".travis.yml"
78
+ - CHANGELOG.md
78
79
  - Gemfile
79
80
  - Gemfile.lock
80
81
  - LICENSE.txt
@@ -83,9 +84,9 @@ files:
83
84
  - bin/console
84
85
  - bin/setup
85
86
  - lib/meta_enum.rb
86
- - lib/meta_enum/missing_value.rb
87
+ - lib/meta_enum/element.rb
88
+ - lib/meta_enum/missing_element.rb
87
89
  - lib/meta_enum/type.rb
88
- - lib/meta_enum/value.rb
89
90
  - lib/meta_enum/version.rb
90
91
  - meta_enum.gemspec
91
92
  homepage: https://github.com/ccsalespro/meta_enum