ruby-ode 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: 4cbd1b654f43bac29c7be4dd5a330d31fe66d056dcb9760fce801a3674dab572
4
+ data.tar.gz: 575f036138804d7760f9827f9cec5270ea8ead5bccd87462e9cddaf7f81423a1
5
+ SHA512:
6
+ metadata.gz: 8ed3d1ef2b00b2032182041e1ce1af0af1ca4664bd37eb40f265710c93697ed7d7f1c3f1a37c9286cbf9bf53d1a1533ab63bf42df21dcc794f77166159560a8a
7
+ data.tar.gz: 90a038e33b4e40b57bd53f1fe20cb5199d3777d22d74111333c13d5e1b6a06a07c57049e74930156f33dfe61bf5e1386675e90a33bc921767b285df55c5374f0
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - created the standalone `ruby-ode` gem runtime
6
+ - added direct, chain, sequence and guard-oriented primitives
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,3 @@
1
+ # Contributing
2
+
3
+ Preserve the ODE vocabulary and keep explanations aligned with the other runtimes when the concept is identical.
data/PUBLICATION.md ADDED
@@ -0,0 +1,10 @@
1
+ # Publication Guide
2
+
3
+ `ruby-ode` is structured as a standard Ruby gem.
4
+
5
+ Release checklist:
6
+
7
+ 1. Run `ruby -Ilib test/test_runtime.rb`
8
+ 2. Update `CHANGELOG.md`
9
+ 3. Tag `v0.1.0`
10
+ 4. Publish through RubyGems when the repository is ready
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # ruby-ode
2
+
3
+ `ruby-ode` is the Ruby member of the ODE runtime family.
4
+
5
+ It provides:
6
+
7
+ - direct `UseCase` execution
8
+ - `ChainUseCase` dependent comparison flow
9
+ - `SequenceUseCase` ordered execution
10
+ - guard-first rejection before business work begins
11
+
12
+ ## Narrative Readability
13
+
14
+ ODE is designed so code can be read as narrative. A developer should be able to identify `guard`, `execute`, `chain`, `sequence`, `dispatch` and `publish` steps even in a language they do not use every day.
15
+
16
+ This does not mean every runtime has identical syntax. It means the conceptual reading path remains stable enough that a Java developer can follow a Go or Ruby flow, and a Swift developer can follow a TypeScript or Python flow, without relearning the product story from scratch.
17
+
18
+ ## What ODE Does Not Claim
19
+
20
+ ODE does not promise identical syntax across languages, and it does not remove the need to understand native platform idioms. It also does not require every runtime to expose the same UI layer.
21
+
22
+ The reason is pragmatic: forcing textual symmetry across Kotlin, Swift, Go, Ruby, PHP, TypeScript or Python would usually make the libraries feel unnatural inside their host ecosystems. ODE prefers semantic stability over artificial syntactic cloning.
23
+
24
+ ## Validation
25
+
26
+ ```bash
27
+ ruby -Ilib test/test_runtime.rb
28
+ ```
29
+
30
+ ## Repository
31
+
32
+ - source: [github.com/animalab-netizen/ruby-ode](https://github.com/animalab-netizen/ruby-ode)
33
+
34
+ ## Coordinates
35
+
36
+ - gem: `ruby-ode`
37
+ - version: `0.1.0`
38
+
39
+ ## Public API
40
+
41
+ - `RubyODE::UseCase`
42
+ - `RubyODE::ChainUseCase`
43
+ - `RubyODE::SequenceUseCase`
44
+ - `RubyODE::UseCaseDispatcher`
45
+ - `RubyODE::ValueOutput`, `RubyODE::ErrorOutput`, `RubyODE::EmptyOutput`, `RubyODE::Outputs`
46
+ - `RubyODE::HttpError`, `RubyODE::ConnectionError`, `RubyODE::GuardRejectedError`, `RubyODE::UnexpectedResponseError`
47
+
48
+ ## Core Concepts
49
+
50
+ ### 1. UseCase
51
+
52
+ `RubyODE::UseCase` keeps guard, execution and output normalization in the same explicit template flow.
53
+
54
+ ### 2. ChainUseCase
55
+
56
+ `RubyODE::ChainUseCase` models a two-step dependent narrative.
57
+
58
+ ### 3. SequenceUseCase
59
+
60
+ `RubyODE::SequenceUseCase` preserves input order across three or more values.
61
+
62
+ ### 4. UseCaseDispatcher
63
+
64
+ `RubyODE::UseCaseDispatcher` triggers a use case and can yield the same output to a block for publication.
65
+
66
+ ## Basic Examples
67
+
68
+ ### Direct UseCase
69
+
70
+ ```ruby
71
+ class LoadPokemonUseCase < RubyODE::UseCase
72
+ def execute(param)
73
+ "spotlight:#{param}"
74
+ end
75
+ end
76
+ ```
77
+
78
+ ### Guarded UseCase
79
+
80
+ ```ruby
81
+ class ComparePokemonUseCase < RubyODE::UseCase
82
+ def guard(param)
83
+ raise RubyODE::GuardRejectedError, "comparison requires distinct entries" if param[0] == param[1]
84
+ end
85
+
86
+ def execute(param)
87
+ "#{param[0]} vs #{param[1]}"
88
+ end
89
+ end
90
+ ```
91
+
92
+ ### Publish While Dispatching
93
+
94
+ ```ruby
95
+ dispatcher = RubyODE::UseCaseDispatcher.new
96
+ output = dispatcher.dispatch("pikachu", LoadPokemonUseCase.new) do |result|
97
+ puts result.inspect
98
+ end
99
+ ```
100
+
101
+ ## Additional Guides
102
+
103
+ - [PUBLICATION.md](/Users/caiosanchezchristino/Desktop/ode-projects/ruby-ode/PUBLICATION.md)
104
+ - [PARITY.md](/Users/caiosanchezchristino/Desktop/ode-projects/ruby-ode/PARITY.md)
105
+ - [USECASE_GUIDE.md](/Users/caiosanchezchristino/Desktop/ode-projects/ruby-ode/USECASE_GUIDE.md)
data/USECASE_GUIDE.md ADDED
@@ -0,0 +1,3 @@
1
+ # UseCase Guide
2
+
3
+ Use `UseCase` for direct delivery, `ChainUseCase` for two-step dependent flow, `SequenceUseCase` for ordered execution across three or more values, and guards to reject invalid dispatch before business work starts.
@@ -0,0 +1,101 @@
1
+ module RubyODE
2
+ class ValueOutput
3
+ attr_reader :value
4
+
5
+ def initialize(value)
6
+ @value = value
7
+ end
8
+ end
9
+
10
+ class ErrorOutput
11
+ attr_reader :error
12
+
13
+ def initialize(error)
14
+ @error = error
15
+ end
16
+ end
17
+
18
+ class EmptyOutput
19
+ end
20
+
21
+ module Outputs
22
+ def self.value(value) = ValueOutput.new(value)
23
+ def self.error(error) = ErrorOutput.new(error)
24
+ def self.empty = EmptyOutput.new
25
+ end
26
+
27
+ class GuardRejectedError < StandardError; end
28
+ class ConnectionError < StandardError; end
29
+ class UnexpectedResponseError < StandardError; end
30
+
31
+ class HttpError < StandardError
32
+ attr_reader :status_code
33
+
34
+ def initialize(status_code, message)
35
+ @status_code = status_code
36
+ super("http #{status_code}: #{message}")
37
+ end
38
+ end
39
+
40
+ class UseCase
41
+ def process(param)
42
+ guard(param)
43
+ on_result(execute(param))
44
+ rescue StandardError => error
45
+ on_error(error)
46
+ end
47
+
48
+ def guard(_param); end
49
+
50
+ def execute(_param)
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def on_result(result)
55
+ Outputs.value(result)
56
+ end
57
+
58
+ def on_error(error)
59
+ Outputs.error(error)
60
+ end
61
+ end
62
+
63
+ class ChainUseCase
64
+ def initialize(first:, second:)
65
+ @first = first
66
+ @second = second
67
+ end
68
+
69
+ def process(param)
70
+ first_output = @first.process(param)
71
+ return Outputs.error(first_output.error) if first_output.is_a?(ErrorOutput)
72
+ return Outputs.empty if first_output.is_a?(EmptyOutput)
73
+
74
+ Outputs.value(@second.call(first_output.value, param))
75
+ rescue StandardError => error
76
+ Outputs.error(error)
77
+ end
78
+ end
79
+
80
+ class SequenceUseCase
81
+ def initialize(step:)
82
+ @step = step
83
+ end
84
+
85
+ def process(values)
86
+ return Outputs.empty if values.empty?
87
+
88
+ Outputs.value(values.map { |value| @step.call(value) })
89
+ rescue StandardError => error
90
+ Outputs.error(error)
91
+ end
92
+ end
93
+
94
+ class UseCaseDispatcher
95
+ def dispatch(param, use_case)
96
+ output = use_case.process(param)
97
+ yield output if block_given?
98
+ output
99
+ end
100
+ end
101
+ end
data/lib/ruby_ode.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative "ruby_ode/runtime"
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-ode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ÂnimaLab
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Ruby runtime for direct, chain, sequence and guard-oriented ODE flows.
13
+ email:
14
+ - animalab.desenvolvimento@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - CHANGELOG.md
20
+ - CONTRIBUTING.md
21
+ - PUBLICATION.md
22
+ - README.md
23
+ - USECASE_GUIDE.md
24
+ - lib/ruby_ode.rb
25
+ - lib/ruby_ode/runtime.rb
26
+ homepage: https://github.com/animalab-netizen/ruby-ode
27
+ licenses:
28
+ - Apache-2.0
29
+ metadata:
30
+ homepage_uri: https://github.com/animalab-netizen/ruby-ode
31
+ source_code_uri: https://github.com/animalab-netizen/ruby-ode
32
+ changelog_uri: https://github.com/animalab-netizen/ruby-ode/blob/main/CHANGELOG.md
33
+ documentation_uri: https://github.com/animalab-netizen/ruby-ode/blob/main/README.md
34
+ bug_tracker_uri: https://github.com/animalab-netizen/ruby-ode/issues
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '3.2'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubygems_version: 4.0.11
50
+ specification_version: 4
51
+ summary: Opinionated delivery engine for Ruby applications.
52
+ test_files: []