fluxus 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: 53b87715576086932fa0632d366b8f17a9abb4790a7115777f2891795e4762bc
4
+ data.tar.gz: 0c1efd6a6a09618de16a27690c936ab6911a751b17f3943f637efcfb35a356e6
5
+ SHA512:
6
+ metadata.gz: f833f3d13d02259e8e6fdb4a003e1af89e2a8a50ae85353122b1bd4a130723acb6a9c1dceacdf1d28692569cae032e0760757e2e1a4c4e8333abb1d94f6f0ec7
7
+ data.tar.gz: ff4fee21d2f14dc6feb32bd3c539643830df5e4d017b27d9edd60705ae468d4c38173133295ef3cfa9eb63ba0d799c07185ecdfab9bed730d2cb7c63f52aa709
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+
4
+ Style/Documentation:
5
+ Enable: false
6
+
7
+ Style/StringLiterals:
8
+ Enabled: true
9
+ EnforcedStyle: single_quotes
10
+
11
+ Style/StringLiteralsInInterpolation:
12
+ Enabled: true
13
+ EnforcedStyle: double_quotes
14
+
15
+ Layout/LineLength:
16
+ Max: 120
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rake', '~> 13.0'
6
+
7
+ group :development, :test do
8
+ gem 'rubocop', '~> 1.21'
9
+
10
+ gem 'byebug', '~> 11'
11
+ gem 'pry', '~> 0.14'
12
+ gem 'pry-byebug', '~> 3.10'
13
+ end
14
+
15
+ group :test do
16
+ gem 'minitest', '~> 5'
17
+ gem 'simplecov', '~> 0.22'
18
+ end
19
+
20
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,83 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fluxus (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.2)
10
+ byebug (11.1.3)
11
+ coderay (1.1.3)
12
+ coveralls (0.7.2)
13
+ multi_json (~> 1.3)
14
+ rest-client (= 1.6.7)
15
+ simplecov (>= 0.7)
16
+ term-ansicolor (= 1.2.2)
17
+ thor (= 0.18.1)
18
+ docile (1.4.0)
19
+ json (2.6.1)
20
+ method_source (1.0.0)
21
+ mime-types (3.4.1)
22
+ mime-types-data (~> 3.2015)
23
+ mime-types-data (3.2022.0105)
24
+ minitest (5.16.3)
25
+ multi_json (1.15.0)
26
+ parallel (1.22.1)
27
+ parser (3.2.0.0)
28
+ ast (~> 2.4.1)
29
+ pry (0.14.2)
30
+ coderay (~> 1.1)
31
+ method_source (~> 1.0)
32
+ pry-byebug (3.10.1)
33
+ byebug (~> 11.0)
34
+ pry (>= 0.13, < 0.15)
35
+ rainbow (3.1.1)
36
+ rake (13.0.6)
37
+ regexp_parser (2.6.2)
38
+ rest-client (1.6.7)
39
+ mime-types (>= 1.16)
40
+ rexml (3.2.5)
41
+ rubocop (1.44.1)
42
+ json (~> 2.3)
43
+ parallel (~> 1.10)
44
+ parser (>= 3.2.0.0)
45
+ rainbow (>= 2.2.2, < 4.0)
46
+ regexp_parser (>= 1.8, < 3.0)
47
+ rexml (>= 3.2.5, < 4.0)
48
+ rubocop-ast (>= 1.24.1, < 2.0)
49
+ ruby-progressbar (~> 1.7)
50
+ unicode-display_width (>= 2.4.0, < 3.0)
51
+ rubocop-ast (1.24.1)
52
+ parser (>= 3.1.1.0)
53
+ ruby-progressbar (1.11.0)
54
+ simplecov (0.22.0)
55
+ docile (~> 1.1)
56
+ simplecov-html (~> 0.11)
57
+ simplecov_json_formatter (~> 0.1)
58
+ simplecov-html (0.12.3)
59
+ simplecov_json_formatter (0.1.4)
60
+ term-ansicolor (1.2.2)
61
+ tins (~> 0.8)
62
+ thor (0.18.1)
63
+ tins (0.13.2)
64
+ unicode-display_width (2.4.2)
65
+
66
+ PLATFORMS
67
+ arm64-darwin-21
68
+ x86_64-linux
69
+
70
+ DEPENDENCIES
71
+ bundler
72
+ byebug (~> 11)
73
+ coveralls
74
+ fluxus!
75
+ minitest (~> 5)
76
+ pry (~> 0.14)
77
+ pry-byebug (~> 3.10)
78
+ rake (~> 13.0)
79
+ rubocop (~> 1.21)
80
+ simplecov (~> 0.22)
81
+
82
+ BUNDLED WITH
83
+ 2.3.7
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Henrique Aparecido Lavezzo
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,241 @@
1
+ # Fluxus
2
+
3
+ [![build](https://github.com/Rynaro/fluxus/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Rynaro/fluxus/actions/workflows/ci.yml)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/e86034a1a2fdc1e8e88b/maintainability)](https://codeclimate.com/github/Rynaro/fluxus/maintainability)
5
+
6
+
7
+ Fluxus [[ˈfluːk.sus]](https://en.wiktionary.org/wiki/fluxus#Latin) is a simple way to bring use cases to your code. The library uses what Ruby can provide and a little taste of pure object-oriented concepts.
8
+
9
+ _This library takes inspiration from the Clean Architecture concepts of use cases._
10
+
11
+ _Some similarities with [dry-monads](https://github.com/dry-rb/dry-monads) and [u-case](https://github.com/serradura/u-case) can easily be perceived. This library operates to bring interoperability with them._
12
+
13
+ ## Installation
14
+
15
+ You can add as your project as a dependency:
16
+
17
+ ```ruby
18
+ gem 'fluxus'
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ An use case is a set of business instructions that will be carefully followed by the runtime code and its dependencies to achieve a great purpose. The level of complexity can vary, but _Fluxus_ is here to create readability and scope around it!
24
+
25
+ _Fluxus_ always tries to deliver more from an object-oriented paradigm than from showing itself. This means _Fluxus_ is more about directions than dependency. And that's why we call our definition classes as `Fluxus::Object` and `Fluxus::SafeObject`.
26
+
27
+ ### Creating a basic Fluxus::Object
28
+
29
+ ```ruby
30
+ class IsEven < Fluxus::Object
31
+ def call!(number)
32
+ return Failure(result: "#{number} is odd") if number.odd?
33
+
34
+ Success(result: "#{number} is even")
35
+ end
36
+ end
37
+
38
+ IsEven.call!(2)
39
+ ```
40
+
41
+ ### Creating a basic Fluxus::SafeObject
42
+
43
+ ```ruby
44
+ class IsEven < Fluxus::SafeObject
45
+ def call!(number)
46
+ return Failure(result: "#{number} is odd") if number.odd?
47
+
48
+ Success(result: "#{number} is even")
49
+ end
50
+ end
51
+
52
+ IsEven.call!(2)
53
+ ```
54
+
55
+ #### Differences of `Object` and `SafeObject`
56
+
57
+ While `Fluxus::Object` preserves the actual Ruby code autonomy to dictate the flow breakers like error management. `SafeObject` stays in the middle and defines safe positions by respecting the `Fluxus` contract and delivering the `Fluxus::Results::Result` interface.
58
+
59
+ This approach could be useful for some error recovery systems. Since the application will always recover from it by using the error as a dependency not a runtime flow control.
60
+
61
+
62
+ ---
63
+
64
+ ### The return `Flow::Results`
65
+
66
+ The expected `Fluxus` contract expects a `Fluxus::Results::Result` interface compatible as a return value.
67
+
68
+ While `Object` (and `SafeObject`) are responsible for delivering a place to hold the actual logic and control this code runtime. The `Results::Result` contract will be responsible for delivering back the necessary hooks and their processed data to the application.
69
+
70
+ We natively support two kinds of `Fluxus::Results::Result` the `Success` and `Failure`. Using this idiom is closer to the natural conception of use cases, when they fail or are successful.
71
+
72
+ #### Success
73
+
74
+ ```ruby
75
+ Success(result: true)
76
+ Success(type: :shinning, result: true)
77
+ ```
78
+
79
+ #### Failure
80
+
81
+ ```ruby
82
+ Failure(result: false)
83
+ Failure(type: :dusty, result: false)
84
+
85
+ ```
86
+
87
+ #### The `Fluxus::Results::Result` contract
88
+
89
+ All results share the same (abstract) ancestor definitions which mean they are interchangeable. This brings more coherence in your code when you are handling the most crucial part of the flow, their results.
90
+
91
+ The `Success` and `Failure` public contracts could be defined by
92
+
93
+ ```ruby
94
+ success_object = Success(type: :ok, result: 1+1)
95
+
96
+ success_object.success? # => true
97
+ success_object.failure? # => false
98
+ success_object.unknown? # => false
99
+
100
+ success_object.type # => :ok
101
+ success_object.data # => 2
102
+
103
+ failure_object = Failure(type: :fail, result: 1-1)
104
+
105
+ failure_object.success? # => false
106
+ failure_object.failure? # => true
107
+ failure_object.unknown? # => false
108
+
109
+ failure_object.type # => :fail
110
+ failure_object.data # => 0
111
+
112
+ ```
113
+
114
+ #### The `result` and `data` relationship
115
+
116
+ You already noticed the `Success` and `Failure` receiving `result:` but getting the data from `data`. In fact, inside the `Fluxus::Results::Result,` the actual contract handles `data` directly. But `result` is a wrapper defined by `Fluxus` to bring more meaning inside the use case concept.
117
+
118
+ #### The `type` importance
119
+
120
+ The `type` is a way to categorize the major events inside the use case. Your use case can hold a variety of `Success` and `Failure` and depend on how the business is defined different paths are taken.
121
+
122
+ The `Fluxus` also defines a default value to bring simplicity to small use cases. The default value is `:ok` for `Success` and `:error` for `Failure`.
123
+
124
+ Prefer using `symbols` for handling those types.
125
+
126
+ #### Results are chainable
127
+
128
+ Was described that `Fluxus::Results::Result` are responsible for handling the (obviously) result. This means, this also needs to control the post-use case without leaking data to the runtime void.
129
+
130
+ With this in mind, the Result implements **chainable** methods. You can call them hooks if you wish.
131
+
132
+ Each hook represents one of the expected states.
133
+
134
+ ```ruby
135
+ Fluxus::Results::Result#on_success
136
+ Fluxus::Results::Result#on_failure
137
+ Fluxus::Results::Result#on_exception
138
+ ```
139
+
140
+ The `on_exception` is a contract for `SafeObject`, but they are basically a `Failure` with a specialized eye for `Exception` looking.
141
+
142
+ #### Hooks are blocks
143
+
144
+ All hooks are essentially blocks, and `data` is available there. This means, you can define the code routine that will handle the `data`, and `data` is immutable. Each hook handles its own version of `data`, and this belongs there.
145
+
146
+ #### Hooks respect `self`
147
+
148
+ All hook implementation preserves the `Success` or `Failure` instance. And this brings a powerful feature to your pipeline. Use cases can chain various conclusions.
149
+
150
+
151
+
152
+ ---
153
+
154
+ ## Compiling the knowledge
155
+
156
+ Using the `IsEven` simple use case, let's implement a fully covered `Fluxus::Object`, so you can fully understand how to build your own use cases.
157
+
158
+ ### Basic flow
159
+
160
+ ```ruby
161
+ class IsEven < Fluxus::Object
162
+ def call!(number)
163
+ return Failure(result: "#{number} is odd") if number.odd?
164
+
165
+ Success(result: "#{number} is even")
166
+ end
167
+ end
168
+
169
+ def my_use_case(number)
170
+ IsEven
171
+ .call!(number)
172
+ .on_success { |data| puts data << '!' }
173
+ .on_failure { |data| puts 'Why? ' << data }
174
+ end
175
+
176
+ my_use_case(2) #=> 2 is even!
177
+ my_use_case(3) #=> Why? 3 is odd
178
+ my_use_case(nil) #=> NoMethodError
179
+ ```
180
+
181
+ ### Scoped Results flow
182
+
183
+ ```ruby
184
+ class IsEven < Fluxus::Object
185
+ def call!(number)
186
+ return Failure(type: :zero, result: 'you got zero') if number.zero?
187
+ return Failure(type: :odd, result: "#{number} is odd") if number.odd?
188
+
189
+ Success(type: :even, result: "#{number} is even")
190
+ end
191
+ end
192
+
193
+ def my_use_case(number)
194
+ IsEven
195
+ .call!(number)
196
+ .on_success(:even) { |data| p data << '!' }
197
+ .on_failure(:odd) { |data| p 'Why? ' << data }
198
+ .on_failure(:zero) { |data| p data }
199
+ end
200
+
201
+ my_use_case(0) #=> you got zero
202
+ my_use_case(2) #=> 2 is even!
203
+ my_use_case(3) #=> Why? 3 is odd
204
+ my_use_case(nil) #=> NoMethodError
205
+ ```
206
+
207
+ ### Safe Results flow
208
+
209
+ ```ruby
210
+ class IsEven < Fluxus::SafeObject
211
+ def call!(number)
212
+ return Failure(type: :zero, result: 'you got zero') if number.zero?
213
+ return Failure(type: :odd, result: "#{number} is odd") if number.odd?
214
+
215
+ Success(type: :even, result: "#{number} is even")
216
+ end
217
+ end
218
+
219
+ def my_use_case(number)
220
+ IsEven
221
+ .call!(number)
222
+ .on_success(:even) { |data| p data << '!' }
223
+ .on_failure(:odd) { |data| p 'Why? ' << data }
224
+ .on_failure(:zero) { |data| p data }
225
+ .on_exception(NoMethodError) { |data| p }
226
+ end
227
+
228
+ my_use_case(0) #=> you got zero
229
+ my_use_case(2) #=> 2 is even!
230
+ my_use_case(3) #=> Why? 3 is odd
231
+ my_use_case(nil) #=> Failure with exception: data
232
+ ```
233
+
234
+
235
+ ## Contributing
236
+
237
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Rynaro/fluxus.
238
+
239
+ ## License
240
+
241
+ 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,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ end
11
+
12
+ require 'rubocop/rake_task'
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fluxus/runner'
4
+
5
+ module Fluxus
6
+ class Caller < Runner
7
+ def self.call!(...)
8
+ __call__(new, ...)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxus
4
+ module Results
5
+ module Chainable
6
+ def on_success(expected_type = nil)
7
+ yield(data) if __success_type?(expected_type)
8
+ self
9
+ end
10
+
11
+ def on_failure(expected_type = nil)
12
+ yield(data) if __failure_type?(expected_type)
13
+ self
14
+ end
15
+
16
+ def on_exception(expected_exception = nil)
17
+ return self unless __failure_type?(:exception)
18
+
19
+ if expected_exception.nil? ||
20
+ (expected_exception.is_a?(Exception) && data[:exception].is_a?(expected_exception))
21
+ yield(data)
22
+ end
23
+ self
24
+ end
25
+
26
+ def __success_type?(expected_type)
27
+ success? && (expected_type.nil? || expected_type == type)
28
+ end
29
+
30
+ def __failure_type?(expected_type = nil)
31
+ failure? && (expected_type.nil? || expected_type == type)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fluxus/results/result'
4
+
5
+ module Fluxus
6
+ module Results
7
+ class Failure < Result
8
+ private
9
+
10
+ def define_state
11
+ :failure
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxus
4
+ module Results
5
+ require 'fluxus/results/chainable'
6
+
7
+ class Result
8
+ include Chainable
9
+ attr_reader :type, :data
10
+
11
+ class StateNotImplemented < StandardError; end
12
+
13
+ def initialize(type: :unknown, data: {})
14
+ @type = type
15
+ @data = data
16
+ @state = define_state
17
+ end
18
+
19
+ def success?
20
+ state == :success
21
+ end
22
+
23
+ def failure?
24
+ state == :failure
25
+ end
26
+
27
+ def unknown?
28
+ !(failure? || success?)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :state
34
+
35
+ def define_state
36
+ raise StateNotImplemented, 'the #define_state hook must be implemented by a concrete class'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fluxus/results/result'
4
+
5
+ module Fluxus
6
+ module Results
7
+ class Success < Result
8
+ private
9
+
10
+ def define_state
11
+ :success
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxus
4
+ require 'fluxus/results/success'
5
+ require 'fluxus/results/failure'
6
+
7
+ class Runner
8
+ class ResultTypeNotDefinedError < StandardError; end
9
+ class CallerNotImplemented < StandardError; end
10
+
11
+ private_class_method :new
12
+
13
+ def self.call!(...)
14
+ raise CallerNotImplemented, 'the flow must be implemented by a caller'
15
+ end
16
+
17
+ def self.__call__(instance, ...)
18
+ result = instance.call!(...)
19
+ raise ResultTypeNotDefinedError, 'flow results must be Success or Failure' unless result.is_a?(Results::Result)
20
+
21
+ result
22
+ end
23
+ private_class_method :__call__
24
+
25
+ def call!
26
+ raise NotImplementedError, '#call! must be implemented'
27
+ end
28
+
29
+ # rubocop:disable Naming/MethodName
30
+ def Success(type: :ok, result: nil)
31
+ @__result = Results::Success.new(type: type, data: result)
32
+ end
33
+
34
+ def Failure(type: :error, result: nil)
35
+ @__result = Results::Failure.new(type: type, data: result)
36
+ end
37
+ # rubocop:enable Naming/MethodName
38
+
39
+ private
40
+
41
+ attr_reader :__result
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fluxus/runner'
4
+
5
+ module Fluxus
6
+ module Safe
7
+ class Caller < Runner
8
+ def self.call!(...)
9
+ instance = new
10
+ __call__(instance, ...)
11
+ rescue StandardError => e
12
+ raise e if e.is_a?(ResultTypeNotDefinedError)
13
+
14
+ instance.Failure(type: :exception, result: { exception: e })
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxus
4
+ VERSION = '0.1.0'
5
+ end
data/lib/fluxus.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fluxus/version'
4
+ require 'fluxus/caller'
5
+ require 'fluxus/safe/caller'
6
+
7
+ module Fluxus
8
+ Object = Caller
9
+ SafeObject = Safe::Caller
10
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluxus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Henrique Aparecido Lavezzo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Really simple fluxus objects for use cases.
28
+ email:
29
+ - hi@hlavezzo.me
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rubocop.yml"
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - lib/fluxus.rb
41
+ - lib/fluxus/caller.rb
42
+ - lib/fluxus/results/chainable.rb
43
+ - lib/fluxus/results/failure.rb
44
+ - lib/fluxus/results/result.rb
45
+ - lib/fluxus/results/success.rb
46
+ - lib/fluxus/runner.rb
47
+ - lib/fluxus/safe/caller.rb
48
+ - lib/fluxus/version.rb
49
+ homepage: https://github.com/Rynaro/fluxus
50
+ licenses:
51
+ - MIT
52
+ metadata:
53
+ homepage_uri: https://github.com/Rynaro/fluxus
54
+ source_code_uri: https://github.com/Rynaro/fluxus
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.7.0
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.2.33
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Simple use case objects
74
+ test_files: []