lib/plumb/steppable.rb in plumb-0.0.2 vs lib/plumb/steppable.rb in plumb-0.0.3
- old
+ new
@@ -8,10 +8,11 @@
%(Undefined)
end
def to_s = inspect
def node_name = :undefined
+ def empty? = true
end
TypeError = Class.new(::TypeError)
Undefined = UndefinedClass.new.freeze
@@ -109,11 +110,11 @@
def transform(target_type, callable = nil, &block)
self >> Transform.new(target_type, callable || block)
end
def check(errors = 'did not pass the check', &block)
- self >> MatchClass.new(block, error: errors)
+ self >> MatchClass.new(block, error: errors, label: errors)
end
def meta(data = {})
self >> Metadata.new(data)
end
@@ -134,26 +135,10 @@
self >> MatchClass.new(*args)
end
def [](val) = match(val)
- DefaultProc = proc do |callable|
- proc do |result|
- result.valid(callable.call)
- end
- end
-
- def default(val = Undefined, &block)
- val_type = if val == Undefined
- DefaultProc.call(block)
- else
- Types::Static[val]
- end
-
- self | (Types::Undefined >> val_type)
- end
-
class Node
include Steppable
attr_reader :node_name, :type, :attributes
@@ -169,35 +154,34 @@
def as_node(node_name, metadata = BLANK_HASH)
Node.new(node_name, self, metadata)
end
- def nullable
- Types::Nil | self
- end
+ # Register a policy for this step.
+ # Mode 1.a: #policy(:name, arg) a single policy with an argument
+ # Mode 1.b: #policy(:name) a single policy without an argument
+ # Mode 2: #policy(p1: value, p2: value) multiple policies with arguments
+ # The latter mode will be expanded to multiple #policy calls.
+ # @return [Step]
+ def policy(*args, &blk)
+ case args
+ in [::Symbol => name, *rest] # #policy(:name, arg)
+ types = Array(metadata[:type]).uniq
- def present
- Types::Present >> self
- end
+ bargs = [self]
+ bargs << rest.first if rest.any?
+ block = Plumb.policies.get(types, name)
+ pol = block.call(*bargs, &blk)
- def options(opts = [])
- rule(included_in: opts)
+ Policy.new(name, rest.first, pol)
+ in [::Hash => opts] # #policy(p1: value, p2: value)
+ opts.reduce(self) { |step, (name, value)| step.policy(name, value) }
+ else
+ raise ArgumentError, "expected a symbol or hash, got #{args.inspect}"
+ end
end
- def rule(*args)
- specs = case args
- in [::Symbol => rule_name, value]
- { rule_name => value }
- in [::Hash => rules]
- rules
- else
- raise ArgumentError, "expected 1 or 2 arguments, but got #{args.size}"
- end
-
- self >> Rules.new(specs, metadata[:type])
- end
-
def ===(other)
case other
when Steppable
other == self
else
@@ -215,11 +199,11 @@
def to_s
inspect
end
- # Build a step that will invoke onr or more methods on the value.
+ # Build a step that will invoke one or more methods on the value.
# Ex 1: Types::String.invoke(:downcase)
# Ex 2: Types::Array.invoke(:[], 1)
# Ex 3 chain of methods: Types::String.invoke([:downcase, :to_sym])
# @return [Step]
def invoke(*args, &block)
@@ -238,7 +222,8 @@
end
end
require 'plumb/deferred'
require 'plumb/transform'
+require 'plumb/policy'
require 'plumb/build'
require 'plumb/metadata'