Module: Igniter::Contracts::Contractable

Defined in:
lib/igniter/contracts/contractable.rb

Defined Under Namespace

Modules: ClassMethods, InstanceMethods Classes: Definition, DefinitionBuilder, ExecutionContext, Observation, Result

Class Method Summary collapse

Class Method Details

.contractable?(target) ⇒ Boolean

Returns:

  • (Boolean)


214
215
216
217
# File 'lib/igniter/contracts/contractable.rb', line 214

def contractable?(target)
  klass = target.is_a?(Class) ? target : target.class
  klass.respond_to?(:contractable_definition)
end

.included(base) ⇒ Object



185
186
187
188
# File 'lib/igniter/contracts/contractable.rb', line 185

def included(base)
  base.extend(ClassMethods)
  base.include(InstanceMethods)
end

.invoke(target, **inputs) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/igniter/contracts/contractable.rb', line 190

def invoke(target, **inputs)
  instance = target.is_a?(Class) ? target.new : target
  definition = instance.class.contractable_definition
  input_error = validate_inputs(definition, inputs)
  return input_error if input_error

  context = ExecutionContext.new
  instance.instance_variable_set(:@__igniter_contractable_context, context)
  raw = instance.public_send(definition.method_name, **inputs)
  result = normalize_result(raw, observations: context.observations)
  result = (result, definition)
  validate_outputs(definition, result)
rescue StandardError => e
  Result.new(
    status: :failure,
    outputs: {},
    observations: context&.observations || [],
    metadata: definition ? (definition) : {},
    error: { code: :contractable_error, message: e.message, class: e.class.name }
  )
ensure
  instance&.remove_instance_variable(:@__igniter_contractable_context) if instance&.instance_variable_defined?(:@__igniter_contractable_context)
end