lite-validation 0.0.1
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 +7 -0
- data/.rubocop.yml +94 -0
- data/Gemfile +18 -0
- data/README.md +770 -0
- data/bench/calibrational.rb +89 -0
- data/bench/comparative.rb +197 -0
- data/bench/functional.rb +107 -0
- data/bench/profile.rb +45 -0
- data/lib/lite/validation/adapters/interfaces/dry.rb +29 -0
- data/lib/lite/validation/error.rb +9 -0
- data/lib/lite/validation/result/abstract/disputable.rb +17 -0
- data/lib/lite/validation/result/abstract/failure.rb +19 -0
- data/lib/lite/validation/result/abstract/refutable.rb +21 -0
- data/lib/lite/validation/result/abstract/success.rb +25 -0
- data/lib/lite/validation/result/abstract.rb +16 -0
- data/lib/lite/validation/structured_error/record.rb +36 -0
- data/lib/lite/validation/structured_error.rb +23 -0
- data/lib/lite/validation/validator/adapters/errors/default.rb +24 -0
- data/lib/lite/validation/validator/adapters/interfaces/default.rb +32 -0
- data/lib/lite/validation/validator/adapters/interfaces/dry.rb +17 -0
- data/lib/lite/validation/validator/adapters/predicates/dry/adapter.rb +50 -0
- data/lib/lite/validation/validator/adapters/predicates/dry/builder.rb +46 -0
- data/lib/lite/validation/validator/adapters/predicates/dry/engine.rb +32 -0
- data/lib/lite/validation/validator/adapters/predicates/dry.rb +3 -0
- data/lib/lite/validation/validator/coordinator/builder.rb +92 -0
- data/lib/lite/validation/validator/coordinator/default.rb +32 -0
- data/lib/lite/validation/validator/coordinator/errors/builder.rb +56 -0
- data/lib/lite/validation/validator/coordinator/errors/dry.rb +29 -0
- data/lib/lite/validation/validator/coordinator/errors/flat.rb +46 -0
- data/lib/lite/validation/validator/coordinator/errors/hierarchical.rb +29 -0
- data/lib/lite/validation/validator/coordinator/instance.rb +30 -0
- data/lib/lite/validation/validator/coordinator.rb +12 -0
- data/lib/lite/validation/validator/helpers/path.rb +49 -0
- data/lib/lite/validation/validator/node/abstract/branch.rb +21 -0
- data/lib/lite/validation/validator/node/abstract/instance.rb +43 -0
- data/lib/lite/validation/validator/node/abstract/leaf.rb +35 -0
- data/lib/lite/validation/validator/node/abstract.rb +25 -0
- data/lib/lite/validation/validator/node/child.rb +44 -0
- data/lib/lite/validation/validator/node/implementation/apply_ruling.rb +44 -0
- data/lib/lite/validation/validator/node/implementation/dig.rb +38 -0
- data/lib/lite/validation/validator/node/implementation/helpers/call_foreign.rb +31 -0
- data/lib/lite/validation/validator/node/implementation/helpers/with_result.rb +23 -0
- data/lib/lite/validation/validator/node/implementation/helpers/yield_strategy.rb +83 -0
- data/lib/lite/validation/validator/node/implementation/helpers/yield_validator.rb +49 -0
- data/lib/lite/validation/validator/node/implementation/identity.rb +90 -0
- data/lib/lite/validation/validator/node/implementation/iteration/iterator.rb +102 -0
- data/lib/lite/validation/validator/node/implementation/iteration.rb +46 -0
- data/lib/lite/validation/validator/node/implementation/navigation.rb +43 -0
- data/lib/lite/validation/validator/node/implementation/predication.rb +61 -0
- data/lib/lite/validation/validator/node/implementation/scoping/evaluator.rb +43 -0
- data/lib/lite/validation/validator/node/implementation/scoping.rb +43 -0
- data/lib/lite/validation/validator/node/implementation/validation.rb +64 -0
- data/lib/lite/validation/validator/node/implementation/wrap.rb +26 -0
- data/lib/lite/validation/validator/node/root.rb +60 -0
- data/lib/lite/validation/validator/node/suspended.rb +33 -0
- data/lib/lite/validation/validator/node.rb +12 -0
- data/lib/lite/validation/validator/option/none.rb +43 -0
- data/lib/lite/validation/validator/option/some/abstract.rb +29 -0
- data/lib/lite/validation/validator/option/some/complex/registry/abstract.rb +67 -0
- data/lib/lite/validation/validator/option/some/complex/registry/node.rb +47 -0
- data/lib/lite/validation/validator/option/some/complex/registry/root.rb +31 -0
- data/lib/lite/validation/validator/option/some/complex/registry.rb +32 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/abstract/iterable.rb +31 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/abstract/non_iterable.rb +27 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/abstract.rb +35 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/array.rb +41 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/hash.rb +40 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/object.rb +34 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers/tuple.rb +47 -0
- data/lib/lite/validation/validator/option/some/complex/wrappers.rb +5 -0
- data/lib/lite/validation/validator/option/some/complex.rb +24 -0
- data/lib/lite/validation/validator/option/some/dig.rb +34 -0
- data/lib/lite/validation/validator/option/some/simple.rb +23 -0
- data/lib/lite/validation/validator/option/some/singular.rb +29 -0
- data/lib/lite/validation/validator/option/some.rb +20 -0
- data/lib/lite/validation/validator/option.rb +20 -0
- data/lib/lite/validation/validator/predicate/abstract/variants.rb +23 -0
- data/lib/lite/validation/validator/predicate/foreign/adapter/input/single.rb +21 -0
- data/lib/lite/validation/validator/predicate/foreign/adapter/input/tuple.rb +21 -0
- data/lib/lite/validation/validator/predicate/foreign/adapter/input.rb +28 -0
- data/lib/lite/validation/validator/predicate/foreign/adapter/ruling/instance.rb +37 -0
- data/lib/lite/validation/validator/predicate/foreign/adapter/ruling.rb +26 -0
- data/lib/lite/validation/validator/predicate/foreign/engine.rb +27 -0
- data/lib/lite/validation/validator/predicate/foreign/variant.rb +33 -0
- data/lib/lite/validation/validator/predicate/foreign/variants.rb +46 -0
- data/lib/lite/validation/validator/predicate/native/builder.rb +72 -0
- data/lib/lite/validation/validator/predicate/native/definite.rb +19 -0
- data/lib/lite/validation/validator/predicate/native/instance.rb +41 -0
- data/lib/lite/validation/validator/predicate/native/optional.rb +34 -0
- data/lib/lite/validation/validator/predicate/registry.rb +47 -0
- data/lib/lite/validation/validator/predicate.rb +17 -0
- data/lib/lite/validation/validator/result/abstract/failure.rb +21 -0
- data/lib/lite/validation/validator/result/abstract/instance.rb +18 -0
- data/lib/lite/validation/validator/result/abstract/success.rb +17 -0
- data/lib/lite/validation/validator/result/abstract.rb +29 -0
- data/lib/lite/validation/validator/result/committed.rb +75 -0
- data/lib/lite/validation/validator/result/disputable/hash.rb +17 -0
- data/lib/lite/validation/validator/result/disputable/instance.rb +43 -0
- data/lib/lite/validation/validator/result/disputable/iterable/array.rb +23 -0
- data/lib/lite/validation/validator/result/disputable/iterable.rb +17 -0
- data/lib/lite/validation/validator/result/disputable/navigable.rb +35 -0
- data/lib/lite/validation/validator/result/disputable.rb +14 -0
- data/lib/lite/validation/validator/result/disputed/abstract/hash.rb +32 -0
- data/lib/lite/validation/validator/result/disputed/abstract/instance.rb +26 -0
- data/lib/lite/validation/validator/result/disputed/iterable/array.rb +42 -0
- data/lib/lite/validation/validator/result/disputed/iterable/hash.rb +38 -0
- data/lib/lite/validation/validator/result/disputed/iterable.rb +20 -0
- data/lib/lite/validation/validator/result/disputed/navigable.rb +59 -0
- data/lib/lite/validation/validator/result/disputed.rb +17 -0
- data/lib/lite/validation/validator/result/refuted.rb +78 -0
- data/lib/lite/validation/validator/result/valid/abstract/collect.rb +42 -0
- data/lib/lite/validation/validator/result/valid/abstract/commit.rb +25 -0
- data/lib/lite/validation/validator/result/valid/abstract/instance.rb +23 -0
- data/lib/lite/validation/validator/result/valid/iterable/array/abstract.rb +24 -0
- data/lib/lite/validation/validator/result/valid/iterable/array/tuples.rb +64 -0
- data/lib/lite/validation/validator/result/valid/iterable/array/values.rb +42 -0
- data/lib/lite/validation/validator/result/valid/iterable/hash.rb +46 -0
- data/lib/lite/validation/validator/result/valid/iterable.rb +33 -0
- data/lib/lite/validation/validator/result/valid/navigable.rb +68 -0
- data/lib/lite/validation/validator/result/valid.rb +21 -0
- data/lib/lite/validation/validator/result.rb +15 -0
- data/lib/lite/validation/validator/ruling/abstract/invalid.rb +59 -0
- data/lib/lite/validation/validator/ruling/abstract/valid.rb +23 -0
- data/lib/lite/validation/validator/ruling/abstract.rb +12 -0
- data/lib/lite/validation/validator/ruling/commit.rb +17 -0
- data/lib/lite/validation/validator/ruling/dispute.rb +21 -0
- data/lib/lite/validation/validator/ruling/invalidate.rb +32 -0
- data/lib/lite/validation/validator/ruling/pass.rb +19 -0
- data/lib/lite/validation/validator/ruling/refute.rb +21 -0
- data/lib/lite/validation/validator/ruling.rb +53 -0
- data/lib/lite/validation/validator/state/instance.rb +46 -0
- data/lib/lite/validation/validator/state/merge_strategy.rb +50 -0
- data/lib/lite/validation/validator/state/unwrap_strategy.rb +31 -0
- data/lib/lite/validation/validator/state.rb +21 -0
- data/lib/lite/validation/validator.rb +15 -0
- data/lib/lite/validation/version.rb +9 -0
- data/lib/lite/validation.rb +8 -0
- metadata +196 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'instance'
|
|
4
|
+
require_relative '../../ruling'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Predicate
|
|
10
|
+
module Native
|
|
11
|
+
class Optional < Instance
|
|
12
|
+
Lite::Data.define(self, kwargs: [:definite])
|
|
13
|
+
|
|
14
|
+
def optional
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def dispute
|
|
19
|
+
with(severity: :dispute, definite: definite&.dispute)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def refute
|
|
23
|
+
with(severity: :refute, definite: definite&.refute)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def validate_value(value)
|
|
27
|
+
definite.call(value)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../error'
|
|
4
|
+
require_relative 'abstract/variants'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Predicate
|
|
10
|
+
module Registry
|
|
11
|
+
def self.register_predicate(key, predicate)
|
|
12
|
+
raise Error, "Not a predicate: #{predicate}" unless predicate.is_a?(Predicate::Abstract::Variants)
|
|
13
|
+
raise Error, "Key already taken: #{key}" if predicates.key?(key)
|
|
14
|
+
|
|
15
|
+
predicates[key] = predicate
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.predicate(key)
|
|
19
|
+
raise Error, "Predicate not registered: #{key}" unless predicates.key?(key)
|
|
20
|
+
|
|
21
|
+
predicates[key]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.predicates
|
|
25
|
+
@predicates ||= {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.register_adapter(key, engine)
|
|
29
|
+
raise Error, "Key already taken: #{key}" if engines.key?(key)
|
|
30
|
+
|
|
31
|
+
engines[key] = engine
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.engine(key)
|
|
35
|
+
raise Error, "Engine not registered: #{key}" unless engines.key?(key)
|
|
36
|
+
|
|
37
|
+
engines[key]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.engines
|
|
41
|
+
@engines ||= {}
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'predicate/registry'
|
|
4
|
+
require_relative 'predicate/native/builder'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Predicate
|
|
10
|
+
def self.define(name, &block)
|
|
11
|
+
predicate = Native::Builder.define(&block)
|
|
12
|
+
Registry.register_predicate(name, predicate)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract'
|
|
4
|
+
|
|
5
|
+
module Lite
|
|
6
|
+
module Validation
|
|
7
|
+
module Validator
|
|
8
|
+
module Result
|
|
9
|
+
module Abstract
|
|
10
|
+
module Failure
|
|
11
|
+
include Validation::Result::Abstract::Failure
|
|
12
|
+
|
|
13
|
+
def to_failure(coordinator)
|
|
14
|
+
coordinator.build_final_error(self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract'
|
|
4
|
+
require 'lite/data'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Abstract
|
|
11
|
+
class Instance
|
|
12
|
+
include Abstract
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract'
|
|
4
|
+
|
|
5
|
+
module Lite
|
|
6
|
+
module Validation
|
|
7
|
+
module Validator
|
|
8
|
+
module Result
|
|
9
|
+
module Abstract
|
|
10
|
+
module Success
|
|
11
|
+
include Validation::Result::Abstract::Success
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../result/abstract'
|
|
4
|
+
require_relative '../../result/abstract/disputable'
|
|
5
|
+
require_relative '../../result/abstract/refutable'
|
|
6
|
+
require_relative '../../error'
|
|
7
|
+
|
|
8
|
+
module Lite
|
|
9
|
+
module Validation
|
|
10
|
+
module Validator
|
|
11
|
+
module Result
|
|
12
|
+
module Abstract
|
|
13
|
+
include Validation::Result::Abstract
|
|
14
|
+
include Validation::Result::Abstract::Disputable
|
|
15
|
+
include Validation::Result::Abstract::Refutable
|
|
16
|
+
|
|
17
|
+
EMPTY = {}.freeze
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def signature(name, data)
|
|
22
|
+
full_name = "Result::#{name}"
|
|
23
|
+
"#<#{[full_name, data].compact.join(' ')}>"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'abstract/instance'
|
|
4
|
+
require_relative 'abstract/success'
|
|
5
|
+
require_relative '../option'
|
|
6
|
+
|
|
7
|
+
module Lite
|
|
8
|
+
module Validation
|
|
9
|
+
module Validator
|
|
10
|
+
module Result
|
|
11
|
+
class Committed < Abstract::Instance
|
|
12
|
+
include Abstract::Success
|
|
13
|
+
|
|
14
|
+
Lite::Data.define(self, args: %i[value])
|
|
15
|
+
|
|
16
|
+
def self.instance(value, *args)
|
|
17
|
+
new(value, *args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private_class_method :new
|
|
21
|
+
|
|
22
|
+
def success_at?(*_path)
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def committed?
|
|
27
|
+
true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def refuted?
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def commit(*)
|
|
35
|
+
prevent_reopening!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def auto_commit(as:)
|
|
39
|
+
prevent_reopening!
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def dispute(_error)
|
|
43
|
+
prevent_reopening!
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def refute(_error)
|
|
47
|
+
prevent_reopening!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def navigate(*_path, &_block)
|
|
51
|
+
prevent_reopening!
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def success
|
|
55
|
+
Option.some(value)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def inspect
|
|
59
|
+
signature('Committed', "value=#{value}")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def recurse(*_path, &_block)
|
|
65
|
+
prevent_reopening!
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def prevent_reopening!
|
|
69
|
+
raise Error::Fatal, "Can't reopen committed result"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract/instance'
|
|
4
|
+
require_relative '../refuted'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputable
|
|
11
|
+
class Instance < Abstract::Instance
|
|
12
|
+
Lite::Data.define(self, args: %i[children])
|
|
13
|
+
|
|
14
|
+
private_class_method :new
|
|
15
|
+
|
|
16
|
+
def committed?
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def refuted?
|
|
21
|
+
false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def refute(error, fall_through: false)
|
|
25
|
+
Refuted.instance(error, fall_through: fall_through)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def enter(key, *rest, &block)
|
|
31
|
+
child = child(key)
|
|
32
|
+
result, meta = child.navigate(*rest, &block)
|
|
33
|
+
return [self, meta] if child.equal?(result)
|
|
34
|
+
return [result, meta] if result.refuted? && result.fall_through
|
|
35
|
+
|
|
36
|
+
[merge(result, key), meta]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../iterable'
|
|
4
|
+
|
|
5
|
+
module Lite
|
|
6
|
+
module Validation
|
|
7
|
+
module Validator
|
|
8
|
+
module Result
|
|
9
|
+
module Disputable
|
|
10
|
+
module Iterable
|
|
11
|
+
module Array
|
|
12
|
+
include Iterable
|
|
13
|
+
|
|
14
|
+
def child(_key)
|
|
15
|
+
Result.valid
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'hash'
|
|
4
|
+
|
|
5
|
+
module Lite
|
|
6
|
+
module Validation
|
|
7
|
+
module Validator
|
|
8
|
+
module Result
|
|
9
|
+
module Disputable
|
|
10
|
+
module Navigable
|
|
11
|
+
include Hash
|
|
12
|
+
|
|
13
|
+
def success_at?(*path)
|
|
14
|
+
if path.empty?
|
|
15
|
+
success?
|
|
16
|
+
else
|
|
17
|
+
key, *rest = path
|
|
18
|
+
child(key).success_at?(*rest)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def navigate(*path, &block)
|
|
23
|
+
if path.empty?
|
|
24
|
+
block.call(self)
|
|
25
|
+
else
|
|
26
|
+
key, *rest = path
|
|
27
|
+
enter(key, *rest, &block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'instance'
|
|
4
|
+
require_relative '../../disputable/hash'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
module Abstract
|
|
12
|
+
class Hash < Abstract::Instance
|
|
13
|
+
include Disputable::Hash
|
|
14
|
+
|
|
15
|
+
Lite::Data.define(self, args: %i[errors_root])
|
|
16
|
+
|
|
17
|
+
def append(result, key)
|
|
18
|
+
raise Error::Fatal, "Key already taken #{key}" if children.key? key
|
|
19
|
+
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def signature(class_name)
|
|
24
|
+
super(class_name, " with #{errors_root.count} root errors, #{children.count} children")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../abstract/failure'
|
|
4
|
+
require_relative '../../disputable/instance'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
module Abstract
|
|
12
|
+
class Instance < Disputable::Instance
|
|
13
|
+
include Result::Abstract::Failure
|
|
14
|
+
|
|
15
|
+
def append(result, key)
|
|
16
|
+
raise Error::Fatal, "Can't append successful result: #{result.inspect}" if result.success?
|
|
17
|
+
|
|
18
|
+
merge(result, key)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract/instance'
|
|
4
|
+
require_relative '../../disputable/iterable/array'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
module Iterable
|
|
12
|
+
class Array < Abstract::Instance
|
|
13
|
+
include Disputable::Iterable::Array
|
|
14
|
+
|
|
15
|
+
def self.instance(*args)
|
|
16
|
+
new([], *args)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def inspect
|
|
20
|
+
signature('Disputed::Iterable::Array')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def navigable
|
|
24
|
+
Disputed.navigable([], children.to_h)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def signature(class_name)
|
|
28
|
+
super(class_name, " with #{children.count} children")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def merge(result, key)
|
|
32
|
+
children << [key, result] unless result.success?
|
|
33
|
+
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../abstract/hash'
|
|
4
|
+
require_relative '../../disputable/iterable'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
module Iterable
|
|
12
|
+
class Hash < Abstract::Hash
|
|
13
|
+
include Disputable::Iterable
|
|
14
|
+
|
|
15
|
+
def self.instance(errors, children)
|
|
16
|
+
new(errors.dup, children.dup)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def inspect
|
|
20
|
+
signature('Disputed::Iterable::Hash')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def navigable
|
|
24
|
+
Disputed.navigable(errors_root, children)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def merge(result, key)
|
|
28
|
+
children.merge!(key => result) unless result.success?
|
|
29
|
+
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'iterable/array'
|
|
4
|
+
require_relative 'iterable/hash'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
module Iterable
|
|
12
|
+
def self.initial
|
|
13
|
+
Array.instance
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'iterable'
|
|
4
|
+
require_relative '../disputable/navigable'
|
|
5
|
+
|
|
6
|
+
module Lite
|
|
7
|
+
module Validation
|
|
8
|
+
module Validator
|
|
9
|
+
module Result
|
|
10
|
+
module Disputed
|
|
11
|
+
class Navigable < Abstract::Hash
|
|
12
|
+
include Disputable::Navigable
|
|
13
|
+
|
|
14
|
+
def self.instance(*args, error: nil)
|
|
15
|
+
instance = new([], EMPTY, *args)
|
|
16
|
+
error ? instance.dispute(error) : instance
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(errors, children, *args)
|
|
20
|
+
super(errors.freeze, children.freeze, *args)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def commit(_value)
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def auto_commit(as:)
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def dispute(error)
|
|
32
|
+
raise Error::Fatal, "Structured error expected, got: #{error.inspect}" unless error.is_a?(StructuredError)
|
|
33
|
+
|
|
34
|
+
self.class.send :new, [*errors_root, error], children
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def inspect
|
|
38
|
+
signature('Disputed::Navigable')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def iterable(commit:)
|
|
42
|
+
Iterable::Hash.instance(errors_root, children)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def merge(result, key)
|
|
46
|
+
return self if result.success?
|
|
47
|
+
|
|
48
|
+
self.class.send(
|
|
49
|
+
:new,
|
|
50
|
+
errors_root,
|
|
51
|
+
children.merge(key => result)
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'disputed/navigable'
|
|
4
|
+
|
|
5
|
+
module Lite
|
|
6
|
+
module Validation
|
|
7
|
+
module Validator
|
|
8
|
+
module Result
|
|
9
|
+
module Disputed
|
|
10
|
+
def self.navigable(errors, children)
|
|
11
|
+
Disputed::Navigable.send(:new, errors, children)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|