Module: Operandi::Dsl::Validation
- Defined in:
- lib/operandi/dsl/validation.rb
Overview
Shared validation logic for DSL modules
Class Method Summary collapse
-
.has_argument?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as an argument.
-
.has_output?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as an output.
-
.has_step?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as a step.
-
.require_type_enabled_for?(field_type, service_class) ⇒ Boolean
Check if require_type is enabled for the given field type and service class.
-
.validate_argument_conflicts!(name_sym, service_class) ⇒ Object
Validate argument name doesn't conflict with outputs or steps.
-
.validate_name_conflicts!(name, field_type, service_class) ⇒ Object
Validate that the name doesn't conflict with other defined names.
-
.validate_output_conflicts!(name_sym, service_class) ⇒ Object
Validate output name doesn't conflict with arguments or steps.
-
.validate_reserved_name!(name, field_type, service_class) ⇒ Object
Validate that the name is not a reserved word.
-
.validate_step_conflicts!(name_sym, service_class) ⇒ Object
Validate step name doesn't conflict with arguments or outputs.
-
.validate_symbol_name!(name, field_type, service_class) ⇒ Object
Validate that the name is a symbol.
-
.validate_type_required!(name, field_type, service_class, opts) ⇒ Object
Validate that the type option is provided when require_type is enabled.
Class Method Details
.has_argument?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as an argument
105 106 107 108 109 110 |
# File 'lib/operandi/dsl/validation.rb', line 105 def self.has_argument?(name_sym, service_class) # Check own_arguments (current class) (service_class.respond_to?(:own_arguments) && service_class.own_arguments.key?(name_sym)) || # Check inherited arguments (service_class.superclass.respond_to?(:arguments) && service_class.superclass.arguments.key?(name_sym)) end |
.has_output?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as an output
113 114 115 116 117 118 |
# File 'lib/operandi/dsl/validation.rb', line 113 def self.has_output?(name_sym, service_class) # Check own_outputs (current class) (service_class.respond_to?(:own_outputs) && service_class.own_outputs.key?(name_sym)) || # Check inherited outputs (service_class.superclass.respond_to?(:outputs) && service_class.superclass.outputs.key?(name_sym)) end |
.has_step?(name_sym, service_class) ⇒ Boolean
Check if a name is already defined as a step
121 122 123 124 125 126 127 |
# File 'lib/operandi/dsl/validation.rb', line 121 def self.has_step?(name_sym, service_class) # Check step_operations (current class) for non-removed steps (service_class.respond_to?(:step_operations) && service_class.step_operations.any? { |op| op[:name] == name_sym && op[:action] != :remove }) || # Check inherited steps (service_class.superclass.respond_to?(:steps) && service_class.superclass.steps.key?(name_sym)) end |
.require_type_enabled_for?(field_type, service_class) ⇒ Boolean
Check if require_type is enabled for the given field type and service class
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/operandi/dsl/validation.rb', line 150 def self.require_type_enabled_for?(field_type, service_class) config_key = field_type == :argument ? :require_arg_type : :require_output_type # Check class-level config in the inheritance chain, then fall back to global config klass = service_class while klass.respond_to?(:class_config) class_config = klass.class_config # Check specific config first (require_arg_type or require_output_type) return class_config[config_key] if class_config&.key?(config_key) # Check convenience config (require_type) for backward compatibility return class_config[:require_type] if class_config&.key?(:require_type) klass = klass.superclass end Operandi.config.public_send(config_key) end |
.validate_argument_conflicts!(name_sym, service_class) ⇒ Object
Validate argument name doesn't conflict with outputs or steps
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/operandi/dsl/validation.rb', line 54 def self.validate_argument_conflicts!(name_sym, service_class) # Check against existing outputs if has_output?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as argument name in #{service_class} - " \ "it is already defined as an output" end # Check against existing steps if has_step?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as argument name in #{service_class} - " \ "it is already defined as a step" end end |
.validate_name_conflicts!(name, field_type, service_class) ⇒ Object
Validate that the name doesn't conflict with other defined names
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/operandi/dsl/validation.rb', line 40 def self.validate_name_conflicts!(name, field_type, service_class) name_sym = name.to_sym case field_type when :argument validate_argument_conflicts!(name_sym, service_class) when :output validate_output_conflicts!(name_sym, service_class) when :step validate_step_conflicts!(name_sym, service_class) end end |
.validate_output_conflicts!(name_sym, service_class) ⇒ Object
Validate output name doesn't conflict with arguments or steps
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/operandi/dsl/validation.rb', line 71 def self.validate_output_conflicts!(name_sym, service_class) # Check against existing arguments if has_argument?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as output name in #{service_class} - " \ "it is already defined as an argument" end # Check against existing steps if has_step?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as output name in #{service_class} - " \ "it is already defined as a step" end end |
.validate_reserved_name!(name, field_type, service_class) ⇒ Object
Validate that the name is not a reserved word
27 28 29 30 31 32 33 |
# File 'lib/operandi/dsl/validation.rb', line 27 def self.validate_reserved_name!(name, field_type, service_class) return unless ReservedNames::ALL.include?(name.to_sym) raise Operandi::ReservedNameError, "Cannot use `#{name}` as #{field_type} name in #{service_class} - " \ "it is a reserved word that conflicts with gem methods" end |
.validate_step_conflicts!(name_sym, service_class) ⇒ Object
Validate step name doesn't conflict with arguments or outputs
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/operandi/dsl/validation.rb', line 88 def self.validate_step_conflicts!(name_sym, service_class) # Check against existing arguments if has_argument?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as step name in #{service_class} - " \ "it is already defined as an argument" end # Check against existing outputs if has_output?(name_sym, service_class) raise Operandi::ReservedNameError, "Cannot use `#{name_sym}` as step name in #{service_class} - " \ "it is already defined as an output" end end |
.validate_symbol_name!(name, field_type, service_class) ⇒ Object
Validate that the name is a symbol
14 15 16 17 18 19 20 |
# File 'lib/operandi/dsl/validation.rb', line 14 def self.validate_symbol_name!(name, field_type, service_class) return if name.is_a?(Symbol) raise Operandi::InvalidNameError, "#{field_type.to_s.capitalize} name must be a Symbol, " \ "got #{name.class} (#{name.inspect}) in #{service_class}" end |
.validate_type_required!(name, field_type, service_class, opts) ⇒ Object
Validate that the type option is provided when require_type is enabled
135 136 137 138 139 140 141 142 143 |
# File 'lib/operandi/dsl/validation.rb', line 135 def self.validate_type_required!(name, field_type, service_class, opts) return if opts.key?(:type) return unless require_type_enabled_for?(field_type, service_class) config_name = field_type == :argument ? "require_arg_type" : "require_output_type" raise Operandi::MissingTypeError, "#{field_type.to_s.capitalize} `#{name}` in #{service_class} must have a type specified " \ "(#{config_name} is enabled)" end |