to-result 0.0.2 → 0.0.3

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: 0bf957670d51788e15be5797daeb430d409cc38967e9f3ba93027ce66eefe93c
4
- data.tar.gz: 5500df2709d9dd14780e53858cf6a2a10fe029d90d3c097e11280104983fdf44
3
+ metadata.gz: 842070fb5be7a4388055318b3956091d4869885c76d745c0dd01ba87cde415e5
4
+ data.tar.gz: 0a7c4e93685409f3f96479df8482255e501a88db53523c55d2f5f171255f58a3
5
5
  SHA512:
6
- metadata.gz: 80580831a173303c62330c741bccaa6bb6edad1155ef9639e33c4e1076132cff165b0a7a9d6d91d2a9d472a69841c3f6fd7af9ab177edcbc6488e8d34d958c14
7
- data.tar.gz: 92eda88e706fbe5b330a5417190904d158487e469c726e64d07380e334efb07b9f30def99a2e6f19fa3e354d184cd9892287d18f02dbffe2130cadf5f351abf4
6
+ metadata.gz: c16327c7a1420c8c1b711d98ffd59de246a3221c98dd6a3bae2cf3650c731c558ccbb02effccdd25d6f9f99e0097d030d751cf8c1dac40569b97dd95b4845817
7
+ data.tar.gz: 23d78aac99bc431eb9b47aafe9aca8dde5b95615766a60305ce016638a3c26e74ac632f5c19bf9c913a5ce70a2ba14d187dc3aea99f8c5876155db4ad9cbed34
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in pulsarcli.gemspec
6
+ gemspec
7
+
8
+ gem 'dry-monads', '~> 1.4'
9
+
10
+ gem 'byebug', '~> 11.1'
11
+
12
+ gem 'minitest', '~> 5.16'
13
+
14
+ gem 'mocha', '~> 1.15'
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ to-result (0.0.3)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ byebug (11.1.3)
10
+ concurrent-ruby (1.1.10)
11
+ dry-core (0.8.1)
12
+ concurrent-ruby (~> 1.0)
13
+ dry-monads (1.4.0)
14
+ concurrent-ruby (~> 1.0)
15
+ dry-core (~> 0.7)
16
+ minitest (5.16.3)
17
+ mocha (1.15.0)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ byebug (~> 11.1)
24
+ dry-monads (~> 1.4)
25
+ minitest (~> 5.16)
26
+ mocha (~> 1.15)
27
+ to-result!
28
+
29
+ BUNDLED WITH
30
+ 2.3.15
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Christian
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+
2
+ # ToResult
3
+
4
+ ToResult is a wrapper built over `dry-monads` to make the `Do Notation`, `Result` and `Try` concepts more handy and consistent to use, in particular to implement the **Railway Pattern**.
5
+
6
+ ## Why I created ToResult
7
+
8
+ `dry-monads` is full of edge cases that require to write boilerplate code everytime I want a method to return a `Success` or `Failure`, for example:
9
+
10
+ ```ruby
11
+ def my_method
12
+ Success(another_method.call)
13
+ rescue StandardError => e
14
+ Failure(e)
15
+ end
16
+ ```
17
+
18
+ so I started using `Try`, that makes the code easier to read and faster to write:
19
+ ```ruby
20
+ def my_method
21
+ Try do
22
+ another_method.call
23
+ end.to_result
24
+ end
25
+ ```
26
+
27
+ but I feel like `to_result` is not really visible at the end of the code and if you forget to write it (as always happens to me) your application blows up.
28
+
29
+ But this is not the bigget problem, bear with me.
30
+
31
+ One of the biggest problem is that we cannot use the `Do Notation` inside a `Try` block:
32
+ ```ruby
33
+ # this will return a Failure(Dry::Monads::Do::Halt)
34
+ def my_method
35
+ Try do
36
+ yield Failure('error code')
37
+ end.to_result
38
+ end
39
+ ```
40
+
41
+ and you cannot even use `yield` and `rescue` in the same method:
42
+
43
+ ```ruby
44
+ # this will return a Failure(Dry::Monads::Do::Halt)
45
+ def my_method
46
+ yield Failure('error code')
47
+ rescue StandardError => e
48
+ # e is an instance of Dry::Monads::Do::Halt
49
+ Failure(e)
50
+ end
51
+ ```
52
+
53
+ because they will raise a `Dry::Monads::Do::Halt` exception and the original exception will be forever lost if we do not "unbox" the exception with `e.result`.
54
+
55
+ ## Installation
56
+
57
+ To install with bundler:
58
+ ```bash
59
+ bundle add to-result
60
+ ```
61
+ or with `gem`:
62
+ ```bash
63
+ gem install to-result
64
+ ```
65
+
66
+ ## Usage
67
+
68
+ To use it with instances of a class, just include it
69
+ ```ruby
70
+ require 'to_result'
71
+
72
+ class MyClass
73
+ include ToResultMixin
74
+
75
+ def my_method
76
+ ToResult do
77
+ whatever_method.call
78
+ end
79
+ end
80
+ end
81
+ ```
82
+
83
+ or if you want to use it with Singleton Classes:
84
+ ```ruby
85
+ require 'to_result'
86
+
87
+ class MyClass
88
+ extend ToResultMixin
89
+
90
+ class << self
91
+ def my_method
92
+ ToResult do
93
+ whatever_method.call
94
+ end
95
+ end
96
+ end
97
+ end
98
+ ```
99
+
100
+ now you can always use `ToResult` all the time you wanted to use `Success`, `Failure` or `Try` but with a more convenient interface and consistent behaviour.
101
+
102
+ Look at this:
103
+
104
+ ```ruby
105
+ ToResult { raise StandardError.new('error code') }
106
+ # returns Failure(StandardError('error code'))
107
+
108
+ ToResult { yield Success('hello!') }
109
+ # returns Success('hello!')
110
+
111
+ ToResult { yield Failure('error code') }
112
+ # returns Failure('error code')
113
+
114
+ ToResult { yield Failure(StandardError.new('error code')) }
115
+ # returns Failure(StandardError('error code'))
116
+
117
+ ToResult([YourCustomError]) { yield Failure(YourCustomError.new('error code')) }
118
+ # returns Failure(YourCustomError('error code'))
119
+
120
+ ToResult([ArgumentError]) { yield Failure(YourCustomError.new('error code')) }
121
+ # raises YourCustomError('error code')
122
+ ```
123
+
124
+ ## Roadmap
125
+ I'm already planning to implement some useful features:
126
+ - [x] write more examples/documentation/tests
127
+ - [ ] configurable error logging when an exception is catched inside `DoResult`
128
+ e.g. sending the log to Airbrake or whathever service you are using
129
+ - [ ] transform/process the catched error
130
+ - [ ] any other suggestion would be appreciated 😁
131
+
132
+ ## Authors
133
+
134
+ - [@a-chris](https://www.github.com/a-chris)
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'to-result'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -3,6 +3,17 @@ require 'dry/monads'
3
3
  module ToResultMixin
4
4
  include Dry::Monads[:do, :result, :try]
5
5
 
6
+ Configuration = Struct.new(:on_error)
7
+
8
+ @@configuration = Configuration.new(on_error: nil)
9
+
10
+ #
11
+ # Allow to override the @@configuration fields
12
+ #
13
+ def self.configure
14
+ yield @@configuration
15
+ end
16
+
6
17
  #
7
18
  # ToResult executes a block of code and returns Success or Failure.
8
19
  # All exceptions inherited from StandardError are catched and
@@ -20,8 +31,11 @@ module ToResultMixin
20
31
  Proc.new do
21
32
  f.call
22
33
  rescue Dry::Monads::Do::Halt => e
23
- return e.result
34
+ error = e.result
35
+ @@configuration.on_error.call(error) if @@configuration.on_error.respond_to?(:call)
36
+ return error
24
37
  rescue *exceptions => e
38
+ @@configuration.on_error.call(e) if @@configuration.on_error.respond_to?(:call)
25
39
  raise e
26
40
  end
27
41
  ).to_result
@@ -0,0 +1,5 @@
1
+ class FakeLogger
2
+ def self.log_error
3
+ true
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ require 'minitest/autorun'
2
+ require 'mocha/minitest'
3
+ require 'byebug'
4
+
5
+ require './lib/to-result'
6
+ require './tests/support/fake_logger'
7
+
8
+ class ToResultTest < Minitest::Test
9
+ include ToResultMixin
10
+
11
+ def setup
12
+ super
13
+ @value = 'hello world!'
14
+ end
15
+
16
+ def teardown
17
+ super
18
+
19
+ # reset the configuration after each test
20
+ ToResultMixin.configure { |c| c = {} }
21
+ end
22
+
23
+ def test_string
24
+ assert ToResult { @value } == Success(@value)
25
+ end
26
+
27
+ def test_success
28
+ expected = Success(@value)
29
+ assert ToResult { expected } == Success(expected)
30
+ end
31
+
32
+ def test_exception
33
+ expected = StandardError.new(@value)
34
+ assert ToResult { raise expected } == Failure(expected)
35
+ end
36
+
37
+ def test_exception_included_in_exceptions_list
38
+ expected = ArgumentError.new(@value)
39
+ assert ToResult([ArgumentError]) { raise expected } == Failure(expected)
40
+ end
41
+
42
+ def test_exception_not_included_in_exceptions_list
43
+ expected = NameError.new(@value)
44
+ assert_raises(NameError) { ToResult([ArgumentError]) { raise expected } }
45
+ end
46
+
47
+ def test_yield_failure
48
+ expected = Failure(@value)
49
+ # this will raise a Dry::Monads::Do::Halt exception
50
+ assert ToResult { yield expected } == expected
51
+ end
52
+
53
+ def test_yield_failure_exception
54
+ expected = Failure(StandardError.new(@value))
55
+ # this will raise a Dry::Monads::Do::Halt exception
56
+ assert ToResult { yield expected } == expected
57
+ end
58
+
59
+ def test_on_error
60
+ FakeLogger.expects(:log_error).once
61
+
62
+ ToResultMixin.configure do |c|
63
+ c.on_error = Proc.new { FakeLogger.log_error }
64
+ end
65
+
66
+ ToResult { raise StandardError.new(@value) }
67
+ end
68
+ end
data/to-result.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'to-result'
8
+ s.version = '0.0.3'
9
+ s.summary = 'A wrapper over dry-monads to offer a handy and consistent way to implement the Railway pattern.'
10
+ s.description = 'A wrapper over dry-monads to offer a handy and consistent way to implement the Railway pattern.'
11
+ s.authors = ['Christian Toscano']
12
+ s.homepage = 'https://github.com/a-chris/to-result'
13
+ s.license = 'MIT'
14
+
15
+ s.require_paths = ['lib']
16
+ s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR).reject { |f| (f == '.gitignore') || f =~ /^examples/ }
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: to-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Toscano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-18 00:00:00.000000000 Z
11
+ date: 2022-10-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A wrapper over dry-monads to offer a handy and consistent way to implement
14
14
  the Railway pattern.
@@ -17,7 +17,15 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - lib/to_result.rb
20
+ - Gemfile
21
+ - Gemfile.lock
22
+ - LICENSE
23
+ - README.md
24
+ - bin/console
25
+ - lib/to-result.rb
26
+ - tests/support/fake_logger.rb
27
+ - tests/to_result_test.rb
28
+ - to-result.gemspec
21
29
  homepage: https://github.com/a-chris/to-result
22
30
  licenses:
23
31
  - MIT