bcdd-result 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,44 +2,65 @@
2
2
 
3
3
  class BCDD::Result
4
4
  module Mixin
5
+ module Factory
6
+ def self.module!
7
+ ::Module.new do
8
+ def self.included(base); base.const_set(:ResultMixin, self); end
9
+ def self.extended(base); base.const_set(:ResultMixin, self); end
10
+ end
11
+ end
12
+ end
13
+
5
14
  module Methods
6
15
  def Success(type, value = nil)
7
- Success.new(type: type, value: value, subject: self)
16
+ _ResultAs(Success, type, value)
8
17
  end
9
18
 
10
19
  def Failure(type, value = nil)
11
- Failure.new(type: type, value: value, subject: self)
20
+ _ResultAs(Failure, type, value)
21
+ end
22
+
23
+ private def _ResultAs(kind_class, type, value, halted: nil)
24
+ kind_class.new(type: type, value: value, subject: self, halted: halted)
12
25
  end
13
26
  end
14
27
 
15
28
  module Addons
16
29
  module Continuable
30
+ def Success(type, value = nil)
31
+ _ResultAs(Success, type, value, halted: true)
32
+ end
33
+
17
34
  private def Continue(value)
18
- Success(:continued, value)
35
+ _ResultAs(Success, :continued, value)
19
36
  end
20
37
  end
21
38
 
22
- OPTIONS = { Continue: Continuable }.freeze
39
+ OPTIONS = { continue: Continuable }.freeze
23
40
 
24
- def self.options(names)
25
- Array(names).filter_map { |name| OPTIONS[name] }
26
- end
27
- end
28
-
29
- def self.module!
30
- ::Module.new do
31
- def self.included(base); base.const_set(:ResultMixin, self); end
32
- def self.extended(base); base.const_set(:ResultMixin, self); end
41
+ def self.options(config_flags)
42
+ Config::Options.addon(map: config_flags, from: OPTIONS)
33
43
  end
34
44
  end
35
45
  end
36
46
 
37
- def self.mixin(with: nil)
38
- addons = Mixin::Addons.options(with)
47
+ def self.mixin(config: nil)
48
+ addons = mixin_module::Addons.options(config)
39
49
 
40
- mod = Mixin.module!
41
- mod.send(:include, Mixin::Methods)
42
- mod.send(:include, *addons) unless addons.empty?
50
+ mod = mixin_module::Factory.module!
51
+ mod.send(:include, mixin_module::Methods)
52
+ mod.const_set(:Result, result_factory)
53
+ mod.send(:include, *addons.values) unless addons.empty?
43
54
  mod
44
55
  end
56
+
57
+ def self.mixin_module
58
+ Mixin
59
+ end
60
+
61
+ def self.result_factory
62
+ ::BCDD::Result
63
+ end
64
+
65
+ private_class_method :mixin_module, :result_factory
45
66
  end
@@ -15,7 +15,7 @@ module BCDD::Result::Success::Methods
15
15
 
16
16
  private
17
17
 
18
- def name
18
+ def kind
19
19
  :success
20
20
  end
21
21
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.7.0'
5
+ VERSION = '0.9.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -10,26 +10,42 @@ require_relative 'result/mixin'
10
10
  require_relative 'result/contract'
11
11
  require_relative 'result/expectations'
12
12
  require_relative 'result/context'
13
+ require_relative 'result/config'
13
14
 
14
15
  class BCDD::Result
15
16
  attr_accessor :unknown
16
17
 
17
- attr_reader :subject, :data, :type_checker
18
+ attr_reader :subject, :data, :type_checker, :halted
18
19
 
19
20
  protected :subject
20
21
 
21
22
  private :unknown, :unknown=, :type_checker
22
23
 
23
- def initialize(type:, value:, subject: nil, expectations: nil)
24
- data = Data.new(name, type, value)
24
+ def self.config
25
+ Config.instance
26
+ end
27
+
28
+ def self.configuration
29
+ yield(config)
30
+
31
+ config.freeze
32
+ end
33
+
34
+ def initialize(type:, value:, subject: nil, expectations: nil, halted: nil)
35
+ data = Data.new(kind, type, value)
25
36
 
26
37
  @type_checker = Contract.evaluate(data, expectations)
27
38
  @subject = subject
39
+ @halted = halted || kind == :failure
28
40
  @data = data
29
41
 
30
42
  self.unknown = true
31
43
  end
32
44
 
45
+ def halted?
46
+ halted
47
+ end
48
+
33
49
  def type
34
50
  data.type
35
51
  end
@@ -69,7 +85,7 @@ class BCDD::Result
69
85
  end
70
86
 
71
87
  def and_then(method_name = nil, context = nil)
72
- return self if failure?
88
+ return self if halted?
73
89
 
74
90
  method_name && block_given? and raise ::ArgumentError, 'method_name and block are mutually exclusive'
75
91
 
@@ -105,7 +121,7 @@ class BCDD::Result
105
121
  end
106
122
 
107
123
  def deconstruct_keys(_keys)
108
- { name => { type => value } }
124
+ { kind => { type => value } }
109
125
  end
110
126
 
111
127
  alias eql? ==
@@ -113,7 +129,7 @@ class BCDD::Result
113
129
 
114
130
  private
115
131
 
116
- def name
132
+ def kind
117
133
  :unknown
118
134
  end
119
135
 
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdd/result'
data/sig/bcdd/result.rbs CHANGED
@@ -10,17 +10,23 @@ class BCDD::Result
10
10
 
11
11
  attr_reader data: BCDD::Result::Data
12
12
  attr_reader subject: untyped
13
+ attr_reader halted: bool
14
+
15
+ def self.config: -> BCDD::Result::Config
16
+ def self.configuration: { (BCDD::Result::Config) -> void } -> BCDD::Result::Config
13
17
 
14
18
  def initialize: (
15
19
  type: Symbol,
16
20
  value: untyped,
17
21
  ?subject: untyped,
18
- ?expectations: BCDD::Result::Contract::Evaluator
22
+ ?expectations: BCDD::Result::Contract::Evaluator,
23
+ ?halted: bool
19
24
  ) -> void
20
25
 
21
26
  def type: -> Symbol
22
27
  def value: -> untyped
23
28
 
29
+ def halted?: -> bool
24
30
  def success?: (?Symbol type) -> bool
25
31
  def failure?: (?Symbol type) -> bool
26
32
 
@@ -47,7 +53,7 @@ class BCDD::Result
47
53
 
48
54
  private
49
55
 
50
- def name: -> Symbol
56
+ def kind: -> Symbol
51
57
  def known: (Proc) -> untyped
52
58
  def call_subject_method: (Symbol, untyped) -> BCDD::Result
53
59
  def ensure_result_object: (untyped, origin: Symbol) -> BCDD::Result
@@ -62,7 +68,8 @@ class BCDD::Result
62
68
  def value: -> untyped
63
69
 
64
70
  private
65
- def name: -> Symbol
71
+
72
+ def kind: -> Symbol
66
73
  def type_checker: -> BCDD::Result::Contract::TypeChecker
67
74
  end
68
75
 
@@ -82,7 +89,8 @@ class BCDD::Result
82
89
  def value: -> untyped
83
90
 
84
91
  private
85
- def name: -> Symbol
92
+
93
+ def kind: -> Symbol
86
94
  def type_checker: -> BCDD::Result::Contract::TypeChecker
87
95
  end
88
96
 
@@ -94,10 +102,18 @@ end
94
102
 
95
103
  class BCDD::Result
96
104
  module Mixin
105
+ module Factory
106
+ def self.module!: -> Module
107
+ end
108
+
97
109
  module Methods
98
110
  def Success: (Symbol type, ?untyped value) -> BCDD::Result::Success
99
111
 
100
112
  def Failure: (Symbol type, ?untyped value) -> BCDD::Result::Failure
113
+
114
+ private
115
+
116
+ def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?halted: bool) -> untyped
101
117
  end
102
118
 
103
119
  module Addons
@@ -111,18 +127,20 @@ class BCDD::Result
111
127
 
112
128
  OPTIONS: Hash[Symbol, Module]
113
129
 
114
- def self.options: (Array[Symbol]) -> Array[Module]
130
+ def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
115
131
  end
116
-
117
- def self.module!: -> Module
118
132
  end
119
133
 
120
- def self.mixin: (?with: Array[Symbol]) -> Module
134
+ def self.mixin: (?config: Hash[Symbol, Hash[Symbol, bool]]) -> Module
135
+
136
+ def self.mixin_module: -> singleton(BCDD::Result::Mixin)
137
+
138
+ def self.result_factory: -> singleton(BCDD::Result)
121
139
  end
122
140
 
123
141
  class BCDD::Result
124
142
  class Data
125
- attr_reader name: Symbol
143
+ attr_reader kind: Symbol
126
144
  attr_reader type: Symbol
127
145
  attr_reader value: untyped
128
146
  attr_reader to_h: Hash[Symbol, untyped]
@@ -225,16 +243,14 @@ module BCDD::Result::Contract
225
243
  BCDD::Result::Contract::Evaluator
226
244
  ) -> BCDD::Result::Contract::TypeChecker
227
245
 
228
- ToEnsure: ^(Hash[Symbol, untyped] | Array[Symbol])
229
- -> BCDD::Result::Contract::Evaluator
246
+ ToEnsure: ^(Hash[Symbol, untyped] | Array[Symbol], Hash[Symbol, Hash[Symbol, bool]])
247
+ -> BCDD::Result::Contract::Interface
230
248
 
231
249
  def self.new: (
232
250
  success: Hash[Symbol, untyped] | Array[Symbol],
233
- failure: Hash[Symbol, untyped] | Array[Symbol]
251
+ failure: Hash[Symbol, untyped] | Array[Symbol],
252
+ config: Hash[Symbol, Hash[Symbol, bool]]
234
253
  ) -> BCDD::Result::Contract::Evaluator
235
-
236
- def self.nil_as_valid_value_checking!: (?enabled: bool) -> void
237
- def self.nil_as_valid_value_checking?: -> bool
238
254
  end
239
255
 
240
256
  module BCDD::Result::Contract
@@ -309,7 +325,14 @@ module BCDD::Result::Contract
309
325
  class ForTypesAndValues
310
326
  include Interface
311
327
 
312
- def initialize: (Hash[Symbol, untyped]) -> void
328
+ def initialize: (
329
+ Hash[Symbol, untyped],
330
+ Hash[Symbol, Hash[Symbol, bool]]
331
+ ) -> void
332
+
333
+ private
334
+
335
+ def nil_as_valid_value_checking?: -> bool
313
336
  end
314
337
  end
315
338
 
@@ -334,16 +357,33 @@ end
334
357
 
335
358
  class BCDD::Result::Expectations
336
359
  def self.mixin: (
337
- ?with: Symbol,
360
+ ?config: Hash[Symbol, Hash[Symbol, bool]],
361
+ ?success: Hash[Symbol, untyped] | Array[Symbol],
362
+ ?failure: Hash[Symbol, untyped] | Array[Symbol]
363
+ ) -> Module
364
+
365
+ def self.mixin!: (
366
+ ?config: Hash[Symbol, Hash[Symbol, bool]],
338
367
  ?success: Hash[Symbol, untyped] | Array[Symbol],
339
368
  ?failure: Hash[Symbol, untyped] | Array[Symbol]
340
369
  ) -> Module
341
370
 
371
+ def self.mixin_module: -> singleton(BCDD::Result::Expectations::Mixin)
372
+
373
+ def self.result_factory_without_expectations: -> singleton(BCDD::Result)
374
+
375
+ def self.new: (
376
+ ?subject: untyped,
377
+ ?contract: BCDD::Result::Contract::Evaluator,
378
+ ?halted: bool,
379
+ **untyped
380
+ ) -> (BCDD::Result::Expectations | untyped)
381
+
342
382
  def initialize: (
343
383
  ?subject: untyped,
344
- ?success: Hash[Symbol, untyped] | Array[Symbol],
345
- ?failure: Hash[Symbol, untyped] | Array[Symbol],
346
- ?contract: BCDD::Result::Contract::Evaluator
384
+ ?contract: BCDD::Result::Contract::Evaluator,
385
+ ?halted: bool,
386
+ **untyped
347
387
  ) -> void
348
388
 
349
389
  def Success: (Symbol, ?untyped) -> BCDD::Result::Success
@@ -353,12 +393,24 @@ class BCDD::Result::Expectations
353
393
 
354
394
  private
355
395
 
396
+ def _ResultAs: (singleton(BCDD::Result), Symbol, untyped) -> untyped
397
+
356
398
  attr_reader subject: untyped
357
399
  attr_reader contract: BCDD::Result::Contract::Evaluator
400
+ attr_reader halted: bool
358
401
  end
359
402
 
360
403
  module BCDD::Result::Expectations::Mixin
361
- METHODS: String
404
+ module Factory
405
+ def self.module!: -> Module
406
+ end
407
+
408
+ module Methods
409
+ BASE: String
410
+ FACTORY: String
411
+
412
+ def self.to_eval: (Hash[Symbol, untyped]) -> String
413
+ end
362
414
 
363
415
  module Addons
364
416
  module Continuable
@@ -367,10 +419,8 @@ module BCDD::Result::Expectations::Mixin
367
419
 
368
420
  OPTIONS: Hash[Symbol, Module]
369
421
 
370
- def self.options: (Symbol) -> Array[Module]
422
+ def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
371
423
  end
372
-
373
- def self.module!: -> Module
374
424
  end
375
425
 
376
426
  class BCDD::Result::Context < BCDD::Result
@@ -384,7 +434,8 @@ class BCDD::Result::Context < BCDD::Result
384
434
  type: Symbol,
385
435
  value: untyped,
386
436
  ?subject: untyped,
387
- ?expectations: BCDD::Result::Contract::Evaluator
437
+ ?expectations: BCDD::Result::Contract::Evaluator,
438
+ ?halted: bool
388
439
  ) -> void
389
440
 
390
441
  def and_then: (?Symbol, **untyped) ?{ (Hash[Symbol, untyped]) -> untyped } -> BCDD::Result::Context
@@ -419,10 +470,16 @@ end
419
470
 
420
471
  class BCDD::Result::Context
421
472
  module Mixin
473
+ Factory: singleton(BCDD::Result::Mixin::Factory)
474
+
422
475
  module Methods
423
476
  def Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
424
477
 
425
478
  def Failure: (Symbol, **untyped) -> BCDD::Result::Context::Failure
479
+
480
+ private
481
+
482
+ def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?halted: bool) -> untyped
426
483
  end
427
484
 
428
485
  module Addons
@@ -436,40 +493,27 @@ class BCDD::Result::Context
436
493
 
437
494
  OPTIONS: Hash[Symbol, Module]
438
495
 
439
- def self.options: (Array[Symbol]) -> Array[Module]
496
+ def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
440
497
  end
441
498
  end
442
499
 
443
- def self.mixin: (?with: Array[Symbol]) -> Module
500
+ def self.mixin_module: -> singleton(BCDD::Result::Context::Mixin)
501
+
502
+ def self.result_factory: -> singleton(BCDD::Result::Context)
444
503
  end
445
504
 
446
- class BCDD::Result::Context::Expectations
447
- def self.mixin: (
448
- ?with: Symbol,
449
- ?success: Hash[Symbol, untyped] | Array[Symbol],
450
- ?failure: Hash[Symbol, untyped] | Array[Symbol]
451
- ) -> Module
505
+ class BCDD::Result::Context::Expectations < BCDD::Result::Expectations
506
+ def self.mixin_module: -> singleton(BCDD::Result::Context::Expectations::Mixin)
452
507
 
453
- def initialize: (
454
- ?subject: untyped,
455
- ?success: Hash[Symbol, untyped] | Array[Symbol],
456
- ?failure: Hash[Symbol, untyped] | Array[Symbol],
457
- ?contract: BCDD::Result::Contract::Evaluator
458
- ) -> void
508
+ def self.result_factory_without_expectations: -> singleton(BCDD::Result)
459
509
 
460
510
  def Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
461
511
  def Failure: (Symbol, **untyped) -> BCDD::Result::Context::Failure
462
-
463
- def with: (subject: untyped) -> BCDD::Result::Context::Expectations
464
-
465
- private
466
-
467
- attr_reader subject: untyped
468
- attr_reader contract: BCDD::Result::Contract::Evaluator
469
512
  end
470
513
 
471
514
  module BCDD::Result::Context::Expectations::Mixin
472
- METHODS: String
515
+ Methods: singleton(BCDD::Result::Expectations::Mixin::Methods)
516
+ Factory: singleton(BCDD::Result::Expectations::Mixin::Factory)
473
517
 
474
518
  module Addons
475
519
  module Continuable
@@ -478,6 +522,88 @@ module BCDD::Result::Context::Expectations::Mixin
478
522
 
479
523
  OPTIONS: Hash[Symbol, Module]
480
524
 
481
- def self.options: (Symbol) -> Array[Module]
525
+ def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
482
526
  end
483
527
  end
528
+
529
+ class BCDD::Result::Config
530
+ include Singleton
531
+
532
+ ADDON: Hash[Symbol, Hash[Symbol, untyped]]
533
+ FEATURE: Hash[Symbol, Hash[Symbol, untyped]]
534
+ PATTERN_MATCHING: Hash[Symbol, Hash[Symbol, untyped]]
535
+
536
+ attr_reader addon: BCDD::Result::Config::Switcher
537
+ attr_reader feature: BCDD::Result::Config::Switcher
538
+ attr_reader constant_alias: BCDD::Result::Config::Switcher
539
+ attr_reader pattern_matching: BCDD::Result::Config::Switcher
540
+
541
+ def self.instance: -> BCDD::Result::Config
542
+
543
+ def initialize: -> void
544
+
545
+ def freeze: -> BCDD::Result::Config
546
+ def options: -> Hash[Symbol, BCDD::Result::Config::Switcher]
547
+ def to_h: -> Hash[Symbol, Hash[Symbol | String, bool]]
548
+ end
549
+
550
+ class BCDD::Result::Config::Switcher
551
+ private attr_reader _affects: Hash[Symbol | String, Array[String]]
552
+ private attr_reader _options: Hash[Symbol | String, bool]
553
+ private attr_reader listener: Proc
554
+
555
+ def initialize: (
556
+ options: Hash[Symbol | String, Hash[Symbol, untyped]],
557
+ ?listener: Proc
558
+ ) -> void
559
+
560
+ def freeze: -> BCDD::Result::Config::Switcher
561
+
562
+ def to_h: -> Hash[Symbol | String, bool]
563
+
564
+ def options: -> Hash[Symbol | String, Hash[Symbol, untyped]]
565
+
566
+ def enabled?: (Symbol | String) -> bool
567
+
568
+ def enable!: (*(Symbol | String)) -> Hash[Symbol | String, Hash[Symbol, untyped]]
569
+
570
+ def disable!: (*(Symbol | String)) -> Hash[Symbol | String, Hash[Symbol, untyped]]
571
+
572
+ private
573
+
574
+ def set_many: (Array[Symbol | String], to: bool) -> Hash[Symbol | String, Hash[Symbol, untyped]]
575
+
576
+ def set_one: (Symbol | String, bool) -> void
577
+
578
+ def require_option!: (Array[Symbol | String]) -> void
579
+
580
+ def validate_option!: (Symbol | String) -> void
581
+
582
+ def available_options_message: -> String
583
+ end
584
+
585
+ module BCDD::Result::Config::ConstantAlias
586
+ MAPPING: Hash[String, Hash[Symbol, untyped]]
587
+ OPTIONS: Hash[String, Hash[Symbol, untyped]]
588
+ Listener: Proc
589
+
590
+ def self.switcher: -> BCDD::Result::Config::Switcher
591
+ end
592
+
593
+ module BCDD::Result::Config::Options
594
+ def self.with_defaults: (
595
+ Hash[Symbol, Hash[Symbol, bool]],
596
+ Symbol
597
+ ) -> Hash[Symbol, bool]
598
+
599
+ def self.select: (
600
+ Hash[Symbol, Hash[Symbol, bool]],
601
+ config: Symbol,
602
+ from: Hash[Symbol, untyped]
603
+ ) -> Hash[Symbol, untyped]
604
+
605
+ def self.addon: (
606
+ map: Hash[Symbol, Hash[Symbol, bool]],
607
+ from: Hash[Symbol, Module]
608
+ ) -> Hash[Symbol, Module]
609
+ end
metadata CHANGED
@@ -1,19 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcdd-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-27 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |-
14
- Empower Ruby apps with a pragmatic use of Railway Oriented Programming.
15
-
16
- It's a general-purpose result monad that allows you to create objects representing a success (BCDD::Result::Success) or failure (BCDD::Result::Failure).
13
+ description: Empower Ruby apps with pragmatic use of Result pattern (monad), Railway
14
+ Oriented Programming, and B/CDD.
17
15
  email:
18
16
  - rodrigo.serradura@gmail.com
19
17
  executables: []
@@ -28,7 +26,12 @@ files:
28
26
  - README.md
29
27
  - Rakefile
30
28
  - Steepfile
29
+ - lib/bcdd-result.rb
31
30
  - lib/bcdd/result.rb
31
+ - lib/bcdd/result/config.rb
32
+ - lib/bcdd/result/config/constant_alias.rb
33
+ - lib/bcdd/result/config/options.rb
34
+ - lib/bcdd/result/config/switcher.rb
32
35
  - lib/bcdd/result/context.rb
33
36
  - lib/bcdd/result/context/expectations.rb
34
37
  - lib/bcdd/result/context/expectations/mixin.rb
@@ -55,7 +58,6 @@ files:
55
58
  - lib/bcdd/result/success.rb
56
59
  - lib/bcdd/result/success/methods.rb
57
60
  - lib/bcdd/result/version.rb
58
- - lib/result.rb
59
61
  - sig/bcdd/result.rbs
60
62
  homepage: https://github.com/b-cdd/result
61
63
  licenses:
@@ -84,5 +86,6 @@ requirements: []
84
86
  rubygems_version: 3.4.19
85
87
  signing_key:
86
88
  specification_version: 4
87
- summary: A pragmatic result abstraction (monad based) for Ruby.
89
+ summary: Empower Ruby apps with pragmatic use of Result pattern (monad), Railway Oriented
90
+ Programming, and B/CDD.
88
91
  test_files: []
data/lib/result.rb DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'bcdd/result'
4
-
5
- Object.const_set(:Result, BCDD::Result)