bcdd-result 0.7.0 → 0.9.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.
@@ -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)