datacaster 2.0.2 → 3.1.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.
- checksums.yaml +4 -4
- data/README.md +604 -287
- data/config/locales/en.yml +25 -0
- data/datacaster.gemspec +3 -1
- data/lib/datacaster/absent.rb +4 -0
- data/lib/datacaster/and_node.rb +3 -5
- data/lib/datacaster/and_with_error_aggregation_node.rb +5 -6
- data/lib/datacaster/array_schema.rb +18 -16
- data/lib/datacaster/base.rb +33 -44
- data/lib/datacaster/caster.rb +4 -8
- data/lib/datacaster/checker.rb +8 -10
- data/lib/datacaster/comparator.rb +9 -9
- data/lib/datacaster/config.rb +28 -0
- data/lib/datacaster/context_node.rb +43 -0
- data/lib/datacaster/context_nodes/errors_caster.rb +21 -0
- data/lib/datacaster/context_nodes/i18n.rb +20 -0
- data/lib/datacaster/context_nodes/i18n_keys_mapper.rb +27 -0
- data/lib/datacaster/context_nodes/pass_if.rb +11 -0
- data/lib/datacaster/context_nodes/structure_cleaner.rb +103 -0
- data/lib/datacaster/context_nodes/user_context.rb +20 -0
- data/lib/datacaster/definition_dsl.rb +36 -0
- data/lib/datacaster/hash_mapper.rb +13 -16
- data/lib/datacaster/hash_schema.rb +14 -15
- data/lib/datacaster/i18n_values/base.rb +87 -0
- data/lib/datacaster/i18n_values/key.rb +34 -0
- data/lib/datacaster/i18n_values/scope.rb +28 -0
- data/lib/datacaster/message_keys_merger.rb +8 -15
- data/lib/datacaster/or_node.rb +3 -4
- data/lib/datacaster/predefined.rb +150 -65
- data/lib/datacaster/result.rb +39 -18
- data/lib/datacaster/runtimes/base.rb +47 -0
- data/lib/datacaster/runtimes/i18n.rb +20 -0
- data/lib/datacaster/runtimes/structure_cleaner.rb +47 -0
- data/lib/datacaster/runtimes/user_context.rb +39 -0
- data/lib/datacaster/substitute_i18n.rb +48 -0
- data/lib/datacaster/switch_node.rb +72 -0
- data/lib/datacaster/then_node.rb +7 -8
- data/lib/datacaster/transformer.rb +4 -8
- data/lib/datacaster/trier.rb +9 -11
- data/lib/datacaster/validator.rb +8 -9
- data/lib/datacaster/version.rb +1 -1
- data/lib/datacaster.rb +15 -35
- metadata +60 -10
- data/lib/datacaster/definition_context.rb +0 -20
- data/lib/datacaster/terminator.rb +0 -98
data/lib/datacaster/result.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
require 'dry/monads'
|
2
|
-
|
3
1
|
module Datacaster
|
4
2
|
class Result
|
5
|
-
|
6
|
-
include Dry::Monads[:result]
|
7
|
-
|
8
|
-
def initialize(valid, value_or_errors, meta: nil)
|
3
|
+
def initialize(valid, value_or_errors)
|
9
4
|
@value_or_errors = value_or_errors
|
5
|
+
if !valid && !@value_or_errors.is_a?(Hash) && !@value_or_errors.is_a?(Array)
|
6
|
+
@value_or_errors = Array(@value_or_errors)
|
7
|
+
end
|
8
|
+
|
10
9
|
@valid = !!valid
|
11
|
-
@meta = meta || {}
|
12
10
|
end
|
13
11
|
|
14
12
|
def valid?
|
@@ -19,13 +17,19 @@ module Datacaster
|
|
19
17
|
@valid ? @value_or_errors : nil
|
20
18
|
end
|
21
19
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def value!
|
21
|
+
raise "Tried to unwrap value of error result: #{inspect}" unless valid?
|
22
|
+
value
|
23
|
+
end
|
24
|
+
|
25
|
+
def raw_errors
|
26
26
|
@valid ? nil : @value_or_errors
|
27
27
|
end
|
28
28
|
|
29
|
+
def errors
|
30
|
+
@errors ||= @valid ? nil : resolve_i18n(raw_errors)
|
31
|
+
end
|
32
|
+
|
29
33
|
def inspect
|
30
34
|
if @valid
|
31
35
|
"#<Datacaster::ValidResult(#{@value_or_errors.inspect})>"
|
@@ -35,27 +39,44 @@ module Datacaster
|
|
35
39
|
end
|
36
40
|
|
37
41
|
def to_dry_result
|
38
|
-
@valid
|
42
|
+
if @valid
|
43
|
+
Dry::Monads::Result::Success.new(@value_or_errors)
|
44
|
+
else
|
45
|
+
Dry::Monads::Result::Failure.new(errors)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def resolve_i18n(o)
|
52
|
+
case o
|
53
|
+
when Array
|
54
|
+
o.map { |x| resolve_i18n(x) }
|
55
|
+
when Hash
|
56
|
+
o.transform_values { |x| resolve_i18n(x) }
|
57
|
+
when I18nValues::Base
|
58
|
+
o.resolve
|
59
|
+
else
|
60
|
+
o
|
61
|
+
end
|
39
62
|
end
|
40
63
|
end
|
41
64
|
|
42
|
-
def self.ValidResult(object
|
65
|
+
def self.ValidResult(object)
|
43
66
|
if object.is_a?(Result)
|
44
67
|
raise "Can't create valid result from error #{object.inspect}" unless object.valid?
|
45
|
-
object.meta = meta if meta
|
46
68
|
object
|
47
69
|
else
|
48
|
-
Result.new(true, object
|
70
|
+
Result.new(true, object)
|
49
71
|
end
|
50
72
|
end
|
51
73
|
|
52
|
-
def self.ErrorResult(object
|
74
|
+
def self.ErrorResult(object)
|
53
75
|
if object.is_a?(Result)
|
54
76
|
raise "Can't create error result from valid #{object.inspect}" if object.valid?
|
55
|
-
object.meta = meta if meta
|
56
77
|
object
|
57
78
|
else
|
58
|
-
Result.new(false, object
|
79
|
+
Result.new(false, object)
|
59
80
|
end
|
60
81
|
end
|
61
82
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Datacaster
|
2
|
+
module Runtimes
|
3
|
+
class Base
|
4
|
+
def self.call(r, proc, *args)
|
5
|
+
r.instance_exec(*args, &proc)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.send_to_parent(r, m, *args, &block)
|
9
|
+
parent = r.instance_variable_get(:@parent)
|
10
|
+
not_found!(m) if parent.nil?
|
11
|
+
call(parent, -> { public_send(m, *args, &block) })
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.not_found!(m)
|
15
|
+
raise NoMethodError.new("Method #{m.inspect} is not available in current runtime context")
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(parent = nil)
|
19
|
+
@parent = parent
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(m, *args, &block)
|
23
|
+
self.class.send_to_parent(self, m, *args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to_missing?(m, include_private = false)
|
27
|
+
!@parent.nil? && @parent.respond_to?(m, include_private)
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"#<#{self.class.name} parent: #{@parent.inspect}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
inspect
|
36
|
+
end
|
37
|
+
|
38
|
+
def Success(v)
|
39
|
+
Datacaster.ValidResult(v)
|
40
|
+
end
|
41
|
+
|
42
|
+
def Failure(v)
|
43
|
+
Datacaster.ErrorResult(v)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Datacaster
|
2
|
+
module Runtimes
|
3
|
+
class I18n < Base
|
4
|
+
attr_reader :args
|
5
|
+
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
@args = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def i18n_var!(name, value)
|
12
|
+
@args[name] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def i18n_vars!(map)
|
16
|
+
@args.merge!(map)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Datacaster
|
2
|
+
module Runtimes
|
3
|
+
class StructureCleaner < Base
|
4
|
+
attr_reader :checked_schema
|
5
|
+
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
@checked_schema = {}
|
9
|
+
@should_check_stack = [false]
|
10
|
+
@pointer_stack = [@checked_schema]
|
11
|
+
end
|
12
|
+
|
13
|
+
# Array checked schema are the same as hash one, where
|
14
|
+
# instead of keys there are array indicies
|
15
|
+
def checked_key!(key)
|
16
|
+
if @ignore
|
17
|
+
return yield if block_given?
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
@pointer_stack.last[key] ||= {}
|
22
|
+
@pointer_stack.push(@pointer_stack.last[key])
|
23
|
+
@should_check_stack.push(false)
|
24
|
+
result = yield if block_given?
|
25
|
+
was_checked = @should_check_stack.pop
|
26
|
+
@pointer_stack.pop
|
27
|
+
@pointer_stack.last[key] = true unless was_checked
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def will_check!
|
32
|
+
@should_check_stack[-1] = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def ignore_checks!(&block)
|
36
|
+
@ignore = true
|
37
|
+
result = yield
|
38
|
+
@ignore = false
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def unchecked?
|
43
|
+
@should_check_stack == [false]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Datacaster
|
4
|
+
module Runtimes
|
5
|
+
class UserContext < Base
|
6
|
+
class ContextStruct
|
7
|
+
def initialize(context, node)
|
8
|
+
@context = context
|
9
|
+
@node = node
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(m, *args)
|
13
|
+
if !args.empty? || block_given?
|
14
|
+
return super
|
15
|
+
end
|
16
|
+
|
17
|
+
if @context.key?(m)
|
18
|
+
return @context[m]
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
@node.class.send_to_parent(@node, :context).public_send(m)
|
23
|
+
rescue NoMethodError
|
24
|
+
raise NoMethodError.new("Key #{m.inspect} is not found in the context")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(parent, user_context)
|
30
|
+
super(parent)
|
31
|
+
@context_struct = ContextStruct.new(user_context, self)
|
32
|
+
end
|
33
|
+
|
34
|
+
def context
|
35
|
+
@context_struct
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Datacaster
|
4
|
+
module SubstituteI18n
|
5
|
+
@load_path = []
|
6
|
+
|
7
|
+
def self.exists?(key)
|
8
|
+
!fetch(key).nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.fetch(key)
|
12
|
+
keys = [locale] + key.split('.')
|
13
|
+
|
14
|
+
@translations.each do |hash|
|
15
|
+
result = hash.dig(*keys)
|
16
|
+
return result unless result.nil?
|
17
|
+
end
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_path
|
22
|
+
@load_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.load_path=(array)
|
26
|
+
@load_path = array
|
27
|
+
@translations = array.map { |x| YAML.load_file(x) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.locale
|
31
|
+
'en'
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.locale=(*)
|
35
|
+
raise NotImplementedError.new("Setting locale is not supported, use ruby-i18n instead of datacaster's built-in")
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.t(key, **args)
|
39
|
+
string = fetch(key)
|
40
|
+
return "Translation missing #{key}" unless string
|
41
|
+
|
42
|
+
args.each do |from, to|
|
43
|
+
string = string.gsub("%{#{from}}", to.to_s)
|
44
|
+
end
|
45
|
+
string
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Datacaster
|
2
|
+
class SwitchNode < Base
|
3
|
+
def initialize(base = nil, on_casters = [], else_caster = nil)
|
4
|
+
base = base[0] if base.is_a?(Array) && base.length == 1
|
5
|
+
|
6
|
+
case base
|
7
|
+
when nil
|
8
|
+
@base = nil
|
9
|
+
when Datacaster::Base
|
10
|
+
@base = base
|
11
|
+
when String, Symbol, Array
|
12
|
+
@base = Datacaster::Predefined.pick(base)
|
13
|
+
else
|
14
|
+
raise RuntimeError, "provide a Datacaster::Base instance, a hash key, or an array of keys to switch(...) caster", caller
|
15
|
+
end
|
16
|
+
|
17
|
+
@ons = on_casters
|
18
|
+
@else = else_caster
|
19
|
+
end
|
20
|
+
|
21
|
+
def on(caster_or_value, clause)
|
22
|
+
caster =
|
23
|
+
case caster_or_value
|
24
|
+
when Datacaster::Base
|
25
|
+
caster_or_value
|
26
|
+
else
|
27
|
+
Datacaster::Predefined.compare(caster_or_value)
|
28
|
+
end
|
29
|
+
|
30
|
+
clause = DefinitionDSL.expand(clause)
|
31
|
+
|
32
|
+
self.class.new(@base, @ons + [[caster, clause]], @else)
|
33
|
+
end
|
34
|
+
|
35
|
+
def else(else_caster)
|
36
|
+
raise ArgumentError, "Datacaster: double else clause is not permitted", caller if @else
|
37
|
+
self.class.new(@base, @ons, else_caster)
|
38
|
+
end
|
39
|
+
|
40
|
+
def cast(object, runtime:)
|
41
|
+
if @ons.empty?
|
42
|
+
raise RuntimeError, "switch caster requires at least one 'on' statement: switch(...).on(condition, cast)", caller
|
43
|
+
end
|
44
|
+
|
45
|
+
if @base.nil?
|
46
|
+
switch_result = object
|
47
|
+
else
|
48
|
+
switch_result = @base.with_runtime(runtime).(object)
|
49
|
+
return switch_result unless switch_result.valid?
|
50
|
+
switch_result = switch_result.value
|
51
|
+
end
|
52
|
+
|
53
|
+
@ons.each do |check, clause|
|
54
|
+
result = check.with_runtime(runtime).(switch_result)
|
55
|
+
next unless result.valid?
|
56
|
+
|
57
|
+
return clause.with_runtime(runtime).(object)
|
58
|
+
end
|
59
|
+
|
60
|
+
# all 'on'-s have failed
|
61
|
+
return @else.with_runtime(runtime).(object) if @else
|
62
|
+
|
63
|
+
Datacaster.ErrorResult(
|
64
|
+
I18nValues::Key.new(['.switch', 'datacaster.errors.switch'], value: object)
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect
|
69
|
+
"#<Datacaster::SwitchNode base: #{@base.inspect} on: #{@ons.inspect} else: #{@else.inspect}>"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/datacaster/then_node.rb
CHANGED
@@ -1,29 +1,28 @@
|
|
1
1
|
module Datacaster
|
2
2
|
class ThenNode < Base
|
3
|
-
def initialize(left, then_caster)
|
3
|
+
def initialize(left, then_caster, else_caster = nil)
|
4
4
|
@left = left
|
5
5
|
@then = then_caster
|
6
|
+
@else = else_caster
|
6
7
|
end
|
7
8
|
|
8
9
|
def else(else_caster)
|
9
10
|
raise ArgumentError.new("Datacaster: double else clause is not permitted") if @else
|
10
11
|
|
11
|
-
@
|
12
|
-
self
|
12
|
+
self.class.new(@left, @then, DefinitionDSL.expand(else_caster))
|
13
13
|
end
|
14
14
|
|
15
|
-
def cast(object)
|
15
|
+
def cast(object, runtime:)
|
16
16
|
unless @else
|
17
17
|
raise ArgumentError.new('Datacaster: use "a & b" instead of "a.then(b)" when there is no else-clause')
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
left_result = @left.(object)
|
20
|
+
left_result = @left.with_runtime(runtime).(object)
|
22
21
|
|
23
22
|
if left_result.valid?
|
24
|
-
@then.(left_result)
|
23
|
+
@then.with_runtime(runtime).(left_result.value)
|
25
24
|
else
|
26
|
-
@else.(object)
|
25
|
+
@else.with_runtime(runtime).(object)
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -1,21 +1,17 @@
|
|
1
1
|
module Datacaster
|
2
2
|
class Transformer < Base
|
3
|
-
def initialize(
|
3
|
+
def initialize(&block)
|
4
4
|
raise "Expected block" unless block_given?
|
5
5
|
|
6
|
-
@name = name
|
7
6
|
@transform = block
|
8
7
|
end
|
9
8
|
|
10
|
-
def cast(object)
|
11
|
-
|
12
|
-
object = intermediary_result.value
|
13
|
-
|
14
|
-
Datacaster.ValidResult(@transform.(object))
|
9
|
+
def cast(object, runtime:)
|
10
|
+
Datacaster.ValidResult(Runtimes::Base.(runtime, @transform, object))
|
15
11
|
end
|
16
12
|
|
17
13
|
def inspect
|
18
|
-
"#<Datacaster
|
14
|
+
"#<Datacaster::Transformer>"
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
data/lib/datacaster/trier.rb
CHANGED
@@ -1,27 +1,25 @@
|
|
1
1
|
module Datacaster
|
2
2
|
class Trier < Base
|
3
|
-
def initialize(
|
3
|
+
def initialize(catched_exception, error_key = nil, &block)
|
4
4
|
raise "Expected block" unless block_given?
|
5
5
|
|
6
|
-
@name = name
|
7
|
-
@error = error
|
8
6
|
@catched_exception = Array(catched_exception)
|
9
|
-
@
|
10
|
-
end
|
7
|
+
@try = block
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
@error_keys = ['.try', 'datacaster.errors.try']
|
10
|
+
@error_keys.unshift(error_key) if error_key
|
11
|
+
end
|
15
12
|
|
13
|
+
def cast(object, runtime:)
|
16
14
|
begin
|
17
|
-
Datacaster.ValidResult(
|
15
|
+
Datacaster.ValidResult(Runtimes::Base.(runtime, @try, object))
|
18
16
|
rescue *@catched_exception
|
19
|
-
Datacaster.ErrorResult(
|
17
|
+
Datacaster.ErrorResult(I18nValues::Key.new(@error_keys, value: object))
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
21
|
def inspect
|
24
|
-
"#<Datacaster
|
22
|
+
"#<Datacaster::Trier>"
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
data/lib/datacaster/validator.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_model'
|
2
|
-
|
3
1
|
module Datacaster
|
4
2
|
class Validator < Base
|
5
3
|
@@validations = {}
|
@@ -21,21 +19,22 @@ module Datacaster
|
|
21
19
|
end.new
|
22
20
|
end
|
23
21
|
|
24
|
-
def initialize(validations
|
25
|
-
|
22
|
+
def initialize(validations)
|
23
|
+
require 'active_model'
|
24
|
+
|
25
|
+
if Config.i18n_module == SubstituteI18n
|
26
|
+
raise NotImplementedError, "Using ActiveModel validations requires ruby-i18n or another i18n gem instead of datacaster's built-in", caller
|
27
|
+
end
|
26
28
|
@validator = self.class.create_active_model(validations)
|
27
29
|
end
|
28
30
|
|
29
|
-
def cast(object)
|
30
|
-
intermediary_result = super(object)
|
31
|
-
object = intermediary_result.value
|
32
|
-
|
31
|
+
def cast(object, runtime:)
|
33
32
|
@validator.value = object
|
34
33
|
@validator.valid? ? Datacaster.ValidResult(object) : Datacaster.ErrorResult(@validator.errors[:value])
|
35
34
|
end
|
36
35
|
|
37
36
|
def inspect
|
38
|
-
"#<Datacaster
|
37
|
+
"#<Datacaster::Validator>"
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
data/lib/datacaster/version.rb
CHANGED
data/lib/datacaster.rb
CHANGED
@@ -1,41 +1,23 @@
|
|
1
|
+
require 'zeitwerk'
|
2
|
+
loader = Zeitwerk::Loader.for_gem
|
3
|
+
loader.inflector.inflect('definition_dsl' => 'DefinitionDSL')
|
4
|
+
loader.setup
|
5
|
+
|
1
6
|
require_relative 'datacaster/result'
|
2
|
-
require_relative 'datacaster/version'
|
3
|
-
|
4
|
-
require_relative 'datacaster/absent'
|
5
|
-
require_relative 'datacaster/base'
|
6
|
-
require_relative 'datacaster/predefined'
|
7
|
-
require_relative 'datacaster/definition_context'
|
8
|
-
require_relative 'datacaster/terminator'
|
9
|
-
require_relative 'datacaster/config'
|
10
|
-
|
11
|
-
require_relative 'datacaster/array_schema'
|
12
|
-
require_relative 'datacaster/caster'
|
13
|
-
require_relative 'datacaster/checker'
|
14
|
-
require_relative 'datacaster/comparator'
|
15
|
-
require_relative 'datacaster/hash_mapper'
|
16
|
-
require_relative 'datacaster/hash_schema'
|
17
|
-
require_relative 'datacaster/message_keys_merger'
|
18
|
-
require_relative 'datacaster/transformer'
|
19
|
-
require_relative 'datacaster/trier'
|
20
|
-
|
21
|
-
require_relative 'datacaster/and_node'
|
22
|
-
require_relative 'datacaster/and_with_error_aggregation_node'
|
23
|
-
require_relative 'datacaster/or_node'
|
24
|
-
require_relative 'datacaster/then_node'
|
25
7
|
|
26
8
|
module Datacaster
|
27
9
|
extend self
|
28
10
|
|
29
|
-
def schema(&block)
|
30
|
-
build_schema(
|
11
|
+
def schema(i18n_scope: nil, &block)
|
12
|
+
ContextNodes::StructureCleaner.new(build_schema(i18n_scope: i18n_scope, &block), :fail)
|
31
13
|
end
|
32
14
|
|
33
|
-
def choosy_schema(&block)
|
34
|
-
build_schema(
|
15
|
+
def choosy_schema(i18n_scope: nil, &block)
|
16
|
+
ContextNodes::StructureCleaner.new(build_schema(i18n_scope: i18n_scope, &block), :remove)
|
35
17
|
end
|
36
18
|
|
37
|
-
def partial_schema(&block)
|
38
|
-
build_schema(
|
19
|
+
def partial_schema(i18n_scope: nil, &block)
|
20
|
+
ContextNodes::StructureCleaner.new(build_schema(i18n_scope: i18n_scope, &block), :pass)
|
39
21
|
end
|
40
22
|
|
41
23
|
def absent
|
@@ -44,19 +26,17 @@ module Datacaster
|
|
44
26
|
|
45
27
|
private
|
46
28
|
|
47
|
-
def build_schema(
|
29
|
+
def build_schema(i18n_scope: nil, &block)
|
48
30
|
raise "Expected block" unless block
|
49
31
|
|
50
|
-
|
51
|
-
|
52
|
-
datacaster = definition_context.instance_exec(&block)
|
32
|
+
datacaster = DefinitionDSL.eval(&block)
|
53
33
|
|
54
34
|
unless datacaster.is_a?(Base)
|
55
35
|
raise "Datacaster instance should be returned from a block (e.g. result of 'hash_schema(...)' call)"
|
56
36
|
end
|
57
37
|
|
58
|
-
datacaster = (
|
59
|
-
|
38
|
+
datacaster = datacaster.i18n_scope(i18n_scope) if i18n_scope
|
39
|
+
|
60
40
|
datacaster
|
61
41
|
end
|
62
42
|
end
|