meta_enum 1.0.0 → 2.0.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.
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