option_set 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a8060b52926fea6b9958f27f06f5e6e900e4959214628c9d179bd766ff6e46b2
4
+ data.tar.gz: 83978bd41bad8ed429b5656be2b82ad0658a2b2d3676ac0d6c57cf9710740d3d
5
+ SHA512:
6
+ metadata.gz: 519bfbeee55cc992ddee434eb33fa430857a4466995115a5014ee6a07806ea2bd0d994acd98d0fc78466b223bdeb5401ef8d10134c47e33ade1d51bcf67f8844
7
+ data.tar.gz: 0faf39bb2c5e3fdf8a57722dc837bd623d9daac32097446c1b1b2bb851d79b4f96f0d5106a6bff7bd3f7b9fbdccff5134e7e2b9b6a4b5a52a20195c546e4ce39
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.standard.yml ADDED
@@ -0,0 +1,6 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/standardrb/standard
3
+ ruby_version: 3.1
4
+ plugins:
5
+ - standard-performance
6
+ # - standard-rspec
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-02-25
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Mateus Armando
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # OptionSet
2
+
3
+ TODO: Delete this and the text below, and describe your gem
4
+
5
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/option_set`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+
7
+ ```ruby
8
+
9
+ class ShippingOptions
10
+ include OptionSet
11
+
12
+ define_options :next_day, :second_day, :priority, :standard
13
+
14
+ EXPRESS = ShippingOptions.from(array: [NEXT_DAY, SECOND_DAY])
15
+ ALL = ShippingOptions.from(array: [EXPRESS, PRIORITY, STANDARD])
16
+ end
17
+
18
+ opts = ShippingOptions::EXPRESS
19
+
20
+ opts.next_day? # => true
21
+ opts.second_day? # => true
22
+ opt.priority? # false
23
+ opt.standard? # false
24
+
25
+ opts.remove(ShippingOptions::NEXT_DAY)
26
+ ```
27
+
28
+ ## Installation
29
+
30
+ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
31
+
32
+ Install the gem and add to the application's Gemfile by executing:
33
+
34
+ ```bash
35
+ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
36
+ ```
37
+
38
+ If bundler is not being used to manage dependencies, install the gem by executing:
39
+
40
+ ```bash
41
+ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
42
+ ```
43
+
44
+ ## Usage
45
+
46
+ TODO: Write usage instructions here
47
+
48
+ ## Development
49
+
50
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
+
52
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
53
+
54
+ ## Contributing
55
+
56
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/option_set.
57
+
58
+ ## License
59
+
60
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The OptionSet module provides a way to define and manipulate bit flag options.
4
+ # It allows for defining methods to check, set, and toggle options represented by bit flags.
5
+ #
6
+ # @example Basic usage
7
+ # class Permissions
8
+ # include OptionSet
9
+ # define_options :read, :write, :delete
10
+ # end
11
+ #
12
+ # perms = Permissions.new
13
+ # perms.read! # Set read flag
14
+ # perms.write = true # Set write flag
15
+ # perms.read? # => true
16
+ # perms.contains?(Permissions::DELETE) # => false
17
+ # perms.values # => ["READ", "WRITE"]opt
18
+ #
19
+ # @example Using a hash with custom bit values
20
+ # class Features
21
+ # include OptionSet
22
+ # define_options basic: 1, premium: 2, enterprise: 4
23
+ # end
24
+ #
25
+ module OptionSet
26
+ # Called when this module is included in another class
27
+ #
28
+ # @param base [Class] The class including this module
29
+ # @return [void]
30
+ def self.included(base)
31
+ base.extend(ClassMethods)
32
+ end
33
+
34
+ # Module containing class methods to be extended into the including class
35
+ module ClassMethods
36
+ # Defines options and creates associated methods for bit flag manipulation
37
+ #
38
+ # @overload define_options(*symbols)
39
+ # @param symbols [Array<Symbol>] A list of symbols representing options
40
+ # @example define_options(:read, :write, :execute)
41
+ #
42
+ # @overload define_options(hash)
43
+ # @param hash [Hash{Symbol => Integer}] A hash mapping option names to bit values
44
+ # @example define_options(basic: 1, premium: 2, enterprise: 4)
45
+ #
46
+ # @raise [ArgumentError] If options are not provided as symbols or a hash
47
+ # @return [void]
48
+ def define_options(*options)
49
+ # Initialize option_values, merging from parent if available
50
+ @option_values = {}
51
+
52
+ option_hash = parse_options(options)
53
+ define_option_methods(option_hash)
54
+ end
55
+
56
+ # Creates a new instance with the provided numeric value
57
+ #
58
+ # @param opts [Hash] the options to create an OptionSet.
59
+ # @param opts [Integer] :value The bit value for initializing the option set
60
+ # @param opts [Array<Integer>] :array a list of bits value for initializing the option set
61
+ #
62
+ # @return [OptionSet] A new instance with the specified value
63
+ def from(value: nil, array: [])
64
+ raise ArgumentError, 'Options must be an Array of Symbols or a Integer' if value.nil? && array.empty?
65
+
66
+ input = value || array.reduce(0) { |result, option| result | (option.is_a?(self) ? option.value : option) }
67
+ new(input)
68
+ end
69
+
70
+ private
71
+
72
+ # Parses options into a hash mapping option names to bit values
73
+ #
74
+ # @param options [Array] Options provided to define_options
75
+ # @return [Hash{Symbol => Integer}] A hash mapping option names to bit values
76
+ #
77
+ # @raise [ArgumentError] If options are not provided as symbols or a hash
78
+ def parse_options(options)
79
+ case options.first
80
+ when Symbol
81
+ options.each_with_index.with_object({}) { |(option, index), hash| hash[option] = 1 << index }
82
+ when Hash
83
+ options.first
84
+ else
85
+ raise ArgumentError, 'Options must be an Array of Symbols or a Hash'
86
+ end
87
+ end
88
+
89
+ # Defines methods and constants for each option
90
+ #
91
+ # @param options [Hash{Symbol => Integer}] A hash mapping option names to bit values
92
+ #
93
+ # @return [void]
94
+ def define_option_methods(options)
95
+ options.each do |option, value|
96
+ const_set(option.to_s.upcase, value)
97
+ @option_values[value] = option
98
+
99
+ # Define predicate methods
100
+ define_method(option) { contains?(value) }
101
+ define_method(:"#{option}?") { contains?(value) }
102
+
103
+ # Define mutator methods
104
+ define_method(:"#{option}!") { add(value) }
105
+ define_method(:"#{option}=") { |val| val ? add(value) : remove(value) }
106
+ end
107
+ end
108
+
109
+ # Returns the mapping of option values to option names
110
+ #
111
+ # @return [Hash{Integer => Symbol}] A hash mapping bit values to option names
112
+ # @api private
113
+ def option_values
114
+ @option_values ||= {}
115
+ end
116
+ end
117
+
118
+ private_constant :ClassMethods
119
+
120
+ # @return [Integer] The current bit value
121
+ attr_reader :value
122
+
123
+ # Initialize a new option set
124
+ #
125
+ # @param value [Integer] Initial bit value (default: 0)
126
+ def initialize(value = 0)
127
+ @value = value
128
+ end
129
+
130
+ # Check if the option set contains the specified option
131
+ #
132
+ # @param option [Integer, self] The bit value to check
133
+ # @return [Boolean] true if the option is set, false otherwise
134
+ def contains?(option)
135
+ option = option.value if option.is_a?(self.class)
136
+ (@value & option) == option
137
+ end
138
+
139
+ # Add an option to the set
140
+ #
141
+ # @param option [Integer, self] The bit value to add
142
+ # @return [self] Returns self for method chaining
143
+ def add(option)
144
+ option = option.value if option.is_a?(self.class)
145
+ @value |= option
146
+ self
147
+ end
148
+
149
+ # Remove an option from the set
150
+ #
151
+ # @param option [Integer, self] The bit value to remove
152
+ # @return [self] Returns self for method chaining
153
+ def remove(option)
154
+ option = option.value if option.is_a?(self.class)
155
+ @value &= ~option
156
+ self
157
+ end
158
+
159
+ # Toggle an option in the set
160
+ #
161
+ # @param option [Integer] The bit value to toggle
162
+ # @return [self] Returns self for method chaining
163
+ def toggle(option)
164
+ option = option.value if option.is_a?(self.class)
165
+ @value ^= option
166
+ self
167
+ end
168
+
169
+ # Clear all options in the set
170
+ #
171
+ # @return [self] Returns self for method chainin
172
+ def clear
173
+ @value = 0
174
+ self
175
+ end
176
+
177
+ # Get the symbolic names of all set options
178
+ #
179
+ # @return [Array<Symbol>] Array of uppercase option names that are enabled
180
+ def values
181
+ option_values = self.class.send(:option_values)
182
+ option_values.select { |k, _| contains?(k) }
183
+ .values.map(&:upcase)
184
+ end
185
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OptionSet
4
+ VERSION = "0.1.0"
5
+ end
data/lib/option_set.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'option_set/version'
4
+ require_relative 'option_set/option_set'
5
+
6
+ module OptionSet
7
+ class Error < StandardError; end
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,4 @@
1
+ module OptionSet
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: option_set
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateus
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2025-02-25 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ OptionSet ame it easier to represent bitset types, where individual bits constants,
14
+ it allows the usage to the usual bitset functionalities
15
+ email:
16
+ - Mateus@tester.de
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".rspec"
22
+ - ".standard.yml"
23
+ - CHANGELOG.md
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - lib/option_set.rb
28
+ - lib/option_set/option_set.rb
29
+ - lib/option_set/version.rb
30
+ - sig/option_set.rbs
31
+ homepage: https://gitlab.com/seanlilmateus/option_set
32
+ licenses:
33
+ - MIT
34
+ metadata:
35
+ homepage_uri: https://gitlab.com/seanlilmateus/option_set
36
+ source_code_uri: https://gitlab.com/seanlilmateus/option_set.git
37
+ changelog_uri: https://gitlab.com/seanlilmateus/option_set/CHANGELOG.md
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 3.1.0
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubygems_version: 3.6.2
53
+ specification_version: 4
54
+ summary: A type that presents a mathematical set interface to a bit set.
55
+ test_files: []