flows 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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