lib/finitio/support/contract.rb
module Finitio
class Contract
include Metadata
def initialize(infotype, dresser, undresser, name = nil, metadata = nil)
unless infotype.is_a?(Type)
raise ArgumentError, "Type expected, got `#{infotype}`"
end
unless dresser.respond_to?(:call)
raise ArgumentError, "r(:call) expected, got `#{dresser}`"
end
unless undresser.respond_to?(:call)
raise ArgumentError, "r(:call) expected, got `#{undresser}`"
end
unless name.nil? or name.is_a?(Symbol)
raise ArgumentError, "Symbol expected, got `#{name}`"
end
@name = name
@infotype = infotype
@dresser = dresser
@undresser = undresser
@metadata = metadata
end
attr_reader :name, :infotype, :dresser, :undresser
def bind_ruby_type(clazz)
@dresser = clazz.method(name.to_sym)
@undresser = clazz.instance_method(:"to_#{name}")
end
def hash
infotype.hash ^ dresser.hash ^ undresser.hash
end
def ==(other)
super || (
other.is_a?(Contract) &&
name == other.name &&
infotype == other.infotype &&
dresser == other.dresser &&
undresser == other.undresser
)
end
alias :eql? :==
def resolve_proxies(system)
Contract.new(infotype.resolve_proxies(system), dresser, undresser, name, metadata)
end
def unconstrained
Contract.new(infotype.unconstrained, dresser, undresser, name, metadata)
end
end # class Contract
end # module Finitio