Class: RubyReactor::Validation::SchemaBuilder
- Inherits:
-
Object
- Object
- RubyReactor::Validation::SchemaBuilder
- Defined in:
- lib/ruby_reactor/validation/schema_builder.rb
Class Method Summary collapse
-
.apply_inline_rules(dsl, rules) ⇒ Object
Apply a list of inline rules ([name, type, optional, predicates]) onto a dry-schema DSL context.
-
.build_args(inline_rules, validate_input) ⇒ Object
Compose per-argument inline rules with an optional ‘validate_args` input (block or pre-built schema).
- .build_args_base(inline_rules, block) ⇒ Object
- .build_contract_from_block(&block) ⇒ Object
- .build_from_block(&block) ⇒ Object
-
.build_inline(name, type, optional, predicates) ⇒ Object
Form 1 / 1b — a single named value with an optional type and predicates.
-
.build_macro(name, optional, &block) ⇒ Object
Form 2 — the block receives the macro already bound to the name and optionality (‘required(name)` / `optional(name)`).
-
.schema_for(schema_or_validator) ⇒ Object
Unwrap an InputValidator into its underlying dry-schema; pass dry-schemas through unchanged.
Class Method Details
.apply_inline_rules(dsl, rules) ⇒ Object
Apply a list of inline rules ([name, type, optional, predicates]) onto a dry-schema DSL context.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 72 def self.apply_inline_rules(dsl, rules) rules.each do |name, type, optional, predicates| macro_method = optional ? :optional : :required rule_method = optional ? :maybe : :filled positional = type.is_a?(Symbol) ? [type] : [] kwargs = type.is_a?(Module) ? { type?: type, **predicates } : predicates macro = dsl.public_send(macro_method, name) if kwargs.empty? macro.public_send(rule_method, *positional) else macro.public_send(rule_method, *positional, **kwargs) end end end |
.build_args(inline_rules, validate_input) ⇒ Object
Compose per-argument inline rules with an optional ‘validate_args` input (block or pre-built schema). Block/inline rules are applied first; a pre-built schema is merged last so its rules win.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 45 def self.build_args(inline_rules, validate_input) block = validate_input.is_a?(Proc) ? validate_input : nil prebuilt = !validate_input.nil? && block.nil? ? schema_for(validate_input) : nil composed = build_args_base(inline_rules, block) if prebuilt && composed composed.merge(prebuilt) elsif prebuilt prebuilt else composed end end |
.build_args_base(inline_rules, block) ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 60 def self.build_args_base(inline_rules, block) return Dry::Schema.Params(&block) if inline_rules.empty? && block return nil if inline_rules.empty? Dry::Schema.Params do SchemaBuilder.apply_inline_rules(self, inline_rules) instance_exec(&block) if block end end |
.build_contract_from_block(&block) ⇒ Object
12 13 14 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 12 def self.build_contract_from_block(&block) Class.new(Dry::Validation::Contract, &block).new end |
.build_from_block(&block) ⇒ Object
8 9 10 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 8 def self.build_from_block(&block) Dry::Schema.Params(&block) end |
.build_inline(name, type, optional, predicates) ⇒ Object
Form 1 / 1b — a single named value with an optional type and predicates.
build_inline(:age, :integer, false, { gteq?: 18 })
=> required(:age).filled(:integer, gteq?: 18)
build_inline(:user, User, false, {})
=> required(:user).filled(type?: User)
build_inline(:bio, :string, true, { max_size?: 100 })
=> optional(:bio).maybe(:string, max_size?: 100)
24 25 26 27 28 29 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 24 def self.build_inline(name, type, optional, predicates) rules = [[name, type, optional, predicates]] Dry::Schema.Params do SchemaBuilder.apply_inline_rules(self, rules) end end |
.build_macro(name, optional, &block) ⇒ Object
Form 2 — the block receives the macro already bound to the name and optionality (‘required(name)` / `optional(name)`). Because it is invoked as a block argument (not via instance_eval) the caller’s ‘self` and lexical scope (class constants, helper methods) stay reachable.
35 36 37 38 39 40 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 35 def self.build_macro(name, optional, &block) macro_method = optional ? :optional : :required Dry::Schema.Params do block.call(public_send(macro_method, name)) end end |
.schema_for(schema_or_validator) ⇒ Object
Unwrap an InputValidator into its underlying dry-schema; pass dry-schemas through unchanged.
90 91 92 93 94 95 96 |
# File 'lib/ruby_reactor/validation/schema_builder.rb', line 90 def self.schema_for(schema_or_validator) if schema_or_validator.is_a?(RubyReactor::Validation::InputValidator) schema_or_validator.schema else schema_or_validator end end |