flows 0.0.1 → 0.0.2

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: 79e8e96fb6de7ee4b138c11b64d430e1937f906093f86cb990e1c4c24a3eab3d
4
- data.tar.gz: 3f22f6b60a7d872d779189371f1f5a274296dc302dc5d93b5aba31a83a0a9925
3
+ metadata.gz: 12213313efb3ea2ba0d786043d82ac3ec4279547de96f3b136303eab4078acf9
4
+ data.tar.gz: a383ca5ae142ddf2385f0d17e12f4f41f353c4dae577743638b1d2db8748ba05
5
5
  SHA512:
6
- metadata.gz: 8c3cd416cd84f853d6690b94fda9d721422d5b0f4934bf02036c2294aaa589eb362e3fd95422e333d53b636762080641ee6d18ec40df537b4c6890898b202546
7
- data.tar.gz: b3cb5df724b36cd50edeb107dc5604e965f06f3032b24aed2e734c5a86224f2ed6d15e2bceb977ef8ce8c66debf0bf0736821ef827e1dbe4b1db62d7ce9db40b
6
+ metadata.gz: f4ec655af858b58f0ef7da44cbb79d1fc6dfa9d49c985cc5e4fbc504b349a8ca8d68e7b78be73e1b3ec1c7f28f121f7b2456fd7477ef88f5f04aa537bd63c232
7
+ data.tar.gz: 8cc7a7e6693c47c2463e8bf2dbf1b6ec4492a3c3125dfd97fbbc8a3e9e1af2763ff6e48320c846cd5a72b44d4c49fae84e14a57b2faba8842154b0793e6591f0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flows (0.0.1)
4
+ flows (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.com/ffloyd/flows.svg?branch=master)](https://travis-ci.com/ffloyd/flows)
4
4
  [![codecov](https://codecov.io/gh/ffloyd/flows/branch/master/graph/badge.svg)](https://codecov.io/gh/ffloyd/flows)
5
+ [![Gem Version](https://badge.fury.io/rb/flows.svg)](https://badge.fury.io/rb/flows)
5
6
 
6
7
  _TODO_
7
8
 
data/bin/demo ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'flows'
5
+
6
+ # Helper for demonstrations
7
+ module Demo
8
+ def self.run(name)
9
+ puts '-' * 60
10
+ puts name
11
+ puts '-' * 60
12
+ puts
13
+
14
+ begin
15
+ yield
16
+ rescue StandardError => e
17
+ puts "Exception raised:\n\n#{e.full_message}"
18
+ end
19
+ puts "\n" + '-' * 60 + "\n" * 2
20
+ end
21
+ end
22
+
23
+ # Simple division
24
+ class DivisionOperation
25
+ include Flows::Operation
26
+
27
+ step :check_for_zero
28
+ step :divide
29
+
30
+ success :result
31
+ failure :error
32
+
33
+ def check_for_zero(denominator:, **)
34
+ if denominator.zero?
35
+ err(error: 'Denominator cannot be zero')
36
+ else
37
+ ok
38
+ end
39
+ end
40
+
41
+ def divide(numerator:, denominator:, **)
42
+ ok(result: numerator / denominator)
43
+ end
44
+ end
45
+
46
+ # Division in nested operation - we do division
47
+ class NestedDivisionOperation
48
+ include Flows::Operation
49
+
50
+ step :do_division
51
+
52
+ success :result
53
+ failure :error
54
+
55
+ def do_division(**params)
56
+ DivisionOperation.new.call(**params)
57
+ end
58
+ end
59
+
60
+ Demo.run 'Unwrap Error verbosity' do
61
+ DivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
62
+ end
63
+
64
+ Demo.run 'Unwrap Error verbosity when error happened in nested operation' do
65
+ NestedDivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
66
+ end
@@ -44,7 +44,8 @@ module Flows
44
44
  body: step[:body],
45
45
  preprocessor: method(:node_preprocessor),
46
46
  postprocessor: method(:node_postprocessor),
47
- router: make_router(step)
47
+ router: make_router(step),
48
+ meta: { name: step[:name] }
48
49
  )
49
50
  end
50
51
  end
@@ -53,9 +54,10 @@ module Flows
53
54
  context[:data]
54
55
  end
55
56
 
56
- def node_postprocessor(output, context, _meta)
57
+ def node_postprocessor(output, context, meta)
57
58
  output_data = output.ok? ? output.unwrap : output.error
58
59
  context[:data].merge!(output_data)
60
+ context[:last_step] = meta[:name]
59
61
 
60
62
  output
61
63
  end
@@ -4,11 +4,12 @@ module Flows
4
4
  class Executor
5
5
  include ::Flows::Result::Helpers
6
6
 
7
- def initialize(flow:, success_shapes:, failure_shapes:)
7
+ def initialize(flow:, success_shapes:, failure_shapes:, class_name:)
8
8
  @flow = flow
9
9
 
10
10
  @success_shapes = success_shapes
11
11
  @failure_shapes = failure_shapes
12
+ @operation_class_name = class_name
12
13
  end
13
14
 
14
15
  def call(**params)
@@ -25,7 +26,7 @@ module Flows
25
26
 
26
27
  case last_result
27
28
  when Flows::Result::Ok then build_success_result(status, context)
28
- when Flows::Result::Err then build_failure_result(status, context)
29
+ when Flows::Result::Err then build_failure_result(status, context, last_result)
29
30
  end
30
31
  end
31
32
 
@@ -38,15 +39,16 @@ module Flows
38
39
  ok(status, data)
39
40
  end
40
41
 
41
- def build_failure_result(status, context)
42
+ def build_failure_result(status, context, last_result)
42
43
  raise ::Flows::Operation::NoFailureShapeError if @failure_shapes.nil?
43
44
 
44
45
  shape = @failure_shapes[status]
45
46
  raise ::Flows::Operation::UnexpectedFailureStatusError.new(status, @failure_shapes.keys) if shape.nil?
46
47
 
47
48
  data = extract_data(context[:data], shape)
49
+ meta = build_meta(context, last_result)
48
50
 
49
- err(status, data)
51
+ Flows::Result::Err.new(data, status: status, meta: meta)
50
52
  end
51
53
 
52
54
  def extract_data(output, keys)
@@ -54,6 +56,18 @@ module Flows
54
56
 
55
57
  output.slice(*keys)
56
58
  end
59
+
60
+ def build_meta(context, last_result)
61
+ meta = {
62
+ operation: @operation_class_name,
63
+ step: context[:last_step],
64
+ context_data: context[:data]
65
+ }
66
+
67
+ meta[:nested_metadata] = last_result.meta if last_result.meta.any?
68
+
69
+ meta
70
+ end
57
71
  end
58
72
  end
59
73
  end
@@ -17,16 +17,7 @@ module Flows
17
17
  def initialize
18
18
  _flows_do_checks
19
19
 
20
- flow = ::Flows::Operation::Builder.new(
21
- steps: self.class.steps,
22
- method_source: self
23
- ).call
24
-
25
- @_flows_executor = ::Flows::Operation::Executor.new(
26
- flow: flow,
27
- success_shapes: self.class.success_shapes,
28
- failure_shapes: self.class.failure_shapes
29
- )
20
+ @_flows_executor = _flows_make_executor(_flows_make_flow)
30
21
  end
31
22
 
32
23
  def call(**params)
@@ -39,5 +30,21 @@ module Flows
39
30
  raise NoStepsError if self.class.steps.empty?
40
31
  raise NoSuccessShapeError, self if self.class.success_shapes.nil?
41
32
  end
33
+
34
+ def _flows_make_flow
35
+ ::Flows::Operation::Builder.new(
36
+ steps: self.class.steps,
37
+ method_source: self
38
+ ).call
39
+ end
40
+
41
+ def _flows_make_executor(flow)
42
+ ::Flows::Operation::Executor.new(
43
+ flow: flow,
44
+ success_shapes: self.class.success_shapes,
45
+ failure_shapes: self.class.failure_shapes,
46
+ class_name: self.class.name
47
+ )
48
+ end
42
49
  end
43
50
  end
@@ -2,8 +2,6 @@ module Flows
2
2
  class Result
3
3
  # Wrapper for failure results
4
4
  class Err < Result
5
- class UnwrapError < Flows::Error; end
6
-
7
5
  def initialize(data, status: :failure, meta: {})
8
6
  super
9
7
  end
@@ -17,7 +15,7 @@ module Flows
17
15
  end
18
16
 
19
17
  def unwrap
20
- raise UnwrapError
18
+ raise UnwrapError.new(@status, @data, @meta)
21
19
  end
22
20
 
23
21
  def error
@@ -0,0 +1,30 @@
1
+ module Flows
2
+ class Result
3
+ # Error for unwrapping non-successful result object
4
+ class UnwrapError < Flows::Error
5
+ def initialize(status, data, meta)
6
+ @status = status
7
+ @data = data
8
+ @meta = meta
9
+ end
10
+
11
+ def message
12
+ "You're trying to unwrap non-successful result with status `#{@status.inspect}` and data `#{@data.inspect}`\n\
13
+ Result metadata: `#{@meta.inspect}`"
14
+ end
15
+ end
16
+
17
+ # Error for dealing with failure result as success one
18
+ class NoErrorError < Flows::Error
19
+ def initialize(status, data)
20
+ @status = status
21
+ @data = data
22
+ end
23
+
24
+ def message
25
+ "You're trying to get error data for successful result with status \
26
+ `#{@status.inspect}` and data `#{@data.inspect}`"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,8 +2,6 @@ module Flows
2
2
  class Result
3
3
  # Wrapper for successful results
4
4
  class Ok < Result
5
- class NoErrorError < Flows::Error; end
6
-
7
5
  def initialize(data, status: :success, meta: {})
8
6
  super
9
7
  end
@@ -21,7 +19,7 @@ module Flows
21
19
  end
22
20
 
23
21
  def error
24
- raise NoErrorError
22
+ raise NoErrorError.new(@status, @data)
25
23
  end
26
24
  end
27
25
  end
data/lib/flows/result.rb CHANGED
@@ -13,6 +13,7 @@ module Flows
13
13
  end
14
14
  end
15
15
 
16
+ require_relative 'result/errors'
16
17
  require_relative 'result/ok'
17
18
  require_relative 'result/err'
18
19
  require_relative 'result/helpers'
data/lib/flows/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Flows
2
- VERSION = '0.0.1'.freeze
2
+ VERSION = '0.0.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flows
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Kolesnev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-27 00:00:00.000000000 Z
11
+ date: 2019-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -155,6 +155,7 @@ files:
155
155
  - README.md
156
156
  - Rakefile
157
157
  - bin/console
158
+ - bin/demo
158
159
  - bin/setup
159
160
  - flows.gemspec
160
161
  - lib/flows.rb
@@ -167,6 +168,7 @@ files:
167
168
  - lib/flows/operation/executor.rb
168
169
  - lib/flows/result.rb
169
170
  - lib/flows/result/err.rb
171
+ - lib/flows/result/errors.rb
170
172
  - lib/flows/result/helpers.rb
171
173
  - lib/flows/result/ok.rb
172
174
  - lib/flows/router.rb