lib/nanoc/base/contracts_support.rb in nanoc-4.4.4 vs lib/nanoc/base/contracts_support.rb in nanoc-4.4.5
- old
+ new
@@ -27,29 +27,82 @@
None = Ignorer.instance
ArrayOf = Ignorer.instance
Or = Ignorer.instance
Func = Ignorer.instance
RespondTo = Ignorer.instance
+ Named = Ignorer.instance
+ IterOf = Ignorer.instance
+ HashOf = Ignorer.instance
def contract(*args); end
end
module EnabledContracts
+ class AbstractContract
+ def self.[](*vals)
+ new(*vals)
+ end
+ end
+
+ class Named < AbstractContract
+ def initialize(name)
+ @name = name
+ end
+
+ def valid?(val)
+ val.is_a?(Kernel.const_get(@name))
+ end
+
+ def inspect
+ "#{self.class}(#{@name})"
+ end
+ end
+
+ class IterOf < AbstractContract
+ def initialize(contract)
+ @contract = contract
+ end
+
+ def valid?(val)
+ val.respond_to?(:each) && val.all? { |v| Contract.valid?(v, @contract) }
+ end
+
+ def inspect
+ "#{self.class}(#{@contract})"
+ end
+ end
+
def contract(*args)
Contract(*args)
end
end
- def self.included(base)
+ def self.setup_once
+ @_contracts_support__setup ||= false
+ return @_contracts_support__should_enable if @_contracts_support__setup
+ @_contracts_support__setup = true
+
contracts_loadable =
begin
require 'contracts'
true
rescue LoadError
false
end
- should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
+ @_contracts_support__should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
+
+ if @_contracts_support__should_enable
+ # FIXME: ugly
+ ::Contracts.const_set('Named', EnabledContracts::Named)
+ ::Contracts.const_set('IterOf', EnabledContracts::IterOf)
+ end
+
+ @_contracts_support__should_enable
+ end
+
+ def self.included(base)
+ should_enable = setup_once
if should_enable
unless base.include?(::Contracts::Core)
base.include(::Contracts::Core)
base.extend(EnabledContracts)