class Jet::Contract
Constants
- FLATTEN_ERROR_TYPES
- MAJOR
- MINOR
- TINY
- VERSION
Attributes
checks[R]
types[R]
Public Class Methods
build(*args, &blk)
click to toggle source
# File lib/jet/contract.rb, line 19 def build(*args, &blk) raise ArgumentError, "no block given" unless block_given? Builder.new.tap { |b| b.instance_eval(&blk) }.call(*args) end
checks!(checks)
click to toggle source
# File lib/jet/contract.rb, line 24 def checks!(checks) validate_registry!("checks", checks, Check, :eql) end
checks=(checks)
click to toggle source
# File lib/jet/contract.rb, line 28 def checks=(checks) @checks = checks!(checks) end
new(attributes, keys_in: [String, Symbol], keys_out: :to_sym, **)
click to toggle source
# File lib/jet/contract.rb, line 57 def initialize(attributes, keys_in: [String, Symbol], keys_out: :to_sym, **) @attributes = Jet.type_check_hash!("`attributes`", attributes, Attribute) .transform_keys(&:to_s) @opts = { keys_in: _keys_in(keys_in), keys_out: _keys_out(keys_out) } end
types!(types)
click to toggle source
# File lib/jet/contract.rb, line 32 def types!(types) case types when :http Type::HTTP when :json Type::JSON when :strict Type::Strict else validate_registry!("types", types, Type, :string) end end
types=(types)
click to toggle source
# File lib/jet/contract.rb, line 45 def types=(types) @types = types!(types) end
version()
click to toggle source
# File lib/jet/contract/version.rb, line 10 def self.version VERSION end
Private Class Methods
validate_registry!(name, registry, type, key)
click to toggle source
# File lib/jet/contract.rb, line 51 def validate_registry!(name, registry, type, key) return registry if registry.respond_to?(:[]) && registry[key].is_a?(type) raise ArgumentError, "`#{name}` must be a registry of #{type}" end
Public Instance Methods
[](key)
click to toggle source
# File lib/jet/contract.rb, line 69 def [](key) @attributes[key] end
attributes()
click to toggle source
# File lib/jet/contract.rb, line 73 def attributes @attributes.dup end
call(input, **)
click to toggle source
# File lib/jet/contract.rb, line 64 def call(input, **) results = check_attributes(filter_keys(input.to_h)) failure(results, input) || success(results) end
opts()
click to toggle source
# File lib/jet/contract.rb, line 77 def opts @opts.dup end
rebuild(*args)
click to toggle source
# File lib/jet/contract.rb, line 81 def rebuild(*args) to_builder.(*args) end
to_builder()
click to toggle source
# File lib/jet/contract.rb, line 85 def to_builder Builder.new(@attributes.transform_values(&:to_builder)) end
with(*other_contracts, **opts)
click to toggle source
# File lib/jet/contract.rb, line 89 def with(*other_contracts, **opts) Jet.type_check_each!("`other_contracts`", other_contracts, Contract) self.class.new( other_contracts.each_with_object(attributes) { |c, atts| atts.merge!(c.attributes) }, **self.opts.merge(opts) ) end
Private Instance Methods
_keys_in(classes)
click to toggle source
# File lib/jet/contract.rb, line 100 def _keys_in(classes) Array(classes).map do |c| next String if c == :string next Symbol if c == :symbol Jet.type_check!(":keys_in element #{c}", Class, Module) c end.uniq end
_keys_out(key_type)
click to toggle source
# File lib/jet/contract.rb, line 109 def _keys_out(key_type) if [Symbol, :symbol, :to_sym].include?(key_type) :to_sym elsif [String, :string, :to_s].include?(key_type) :to_s else raise ArgumentError, ":keys_out must equal either :symbol or :string" end end
check_attributes(input)
click to toggle source
# File lib/jet/contract.rb, line 119 def check_attributes(input) @attributes.each_with_object({}) do |(k, att), h| if input.key?(k) h[k] = att.(input[k], k.to_sym) else next if att.optional? h[k] = Result.failure(:key_missing_failure, at: k.to_sym) end end end
failure(results, input)
click to toggle source
# File lib/jet/contract.rb, line 130 def failure(results, input) return unless results.values.any?(&:failure?) Result.failure( :contract_validation_failure, errors: flatten_errors(results.values), input: input ) end
filter_keys(input)
click to toggle source
# File lib/jet/contract.rb, line 139 def filter_keys(input) input.select { |k, _| @opts[:keys_in].any? { |t| k.is_a?(t) } } .transform_keys(&:to_s) .select { |k, _| attributes.keys.include?(k) } end
flatten_errors(results)
click to toggle source
# File lib/jet/contract.rb, line 145 def flatten_errors(results) results.select(&:failure?).each_with_object([]) do |r, errs| next errs.concat(flatten_errors(r.errors)) if FLATTEN_ERROR_TYPES.include?(r.output) errs << r end end
success(results)
click to toggle source
# File lib/jet/contract.rb, line 152 def success(results) results .each_with_object({}) { |(k, r), h| h[k.send(opts[:keys_out])] = r.output } .yield_self { |output| Result.success(output) } end