#------------------------------------------------------------------------------- # Author: Keith Brings # Copyright (C) 2018 Noizu Labs, Inc. All rights reserved. #------------------------------------------------------------------------------- defmodule Noizu.RuleEngine.Op.SwitchOp do @type t :: %__MODULE__{ name: String.t | nil, description: String.t | nil, identifier: String.t | list | tuple, # Materialized Path. condition_clause: any, switch: Map.t, default: any, settings: Keyword.t, } defstruct [ name: nil, description: nil, identifier: nil, condition_clause: nil, switch: %{}, default: nil, settings: [async?: :auto, throw_on_timeout?: :auto] ] end defimpl Noizu.RuleEngine.ScriptProtocol, for: Noizu.RuleEngine.Op.SwitchOp do alias Noizu.RuleEngine.Helper #----------------- # execute!/3 #----------------- def execute!(this, state, context), do: execute!(this, state, context, %{}) #----------------- # execute!/4 #----------------- def execute!(this, state, context, options) do {selector, state} = Noizu.RuleEngine.ScriptProtocol.execute!(this.condition_clause, state, context, options) cond do Map.has_key?(this.switch, selector) -> Noizu.RuleEngine.ScriptProtocol.execute!(this.switch[selector], state, context, options) this.default -> Noizu.RuleEngine.ScriptProtocol.execute!(this.default, state, context, options) true -> throw Noizu.RuleEngine.Error.Basic.new("[ScriptError] #{identifier(this, state, context, options)} No Switch Clause Matches #{inspect selector} and no default provided") end end #--------------------- # identifier/3 #--------------------- def identifier(this, _state, _context), do: Helper.identifier(this) #--------------------- # identifier/4 #--------------------- def identifier(this, _state, _context, _options), do: Helper.identifier(this) #--------------------- # render/3 #--------------------- def render(this, state, context), do: render(this, state, context, %{}) #--------------------- # render/4 #--------------------- def render(this, state, context, options) do tag = "Switch" identifier = identifier(this, state, context, options) depth = options[:depth] || 0 prefix = (depth == 0) && (">> ") || (String.duplicate(" ", ((depth - 1) * 4) + 3) <> "|-- ") options_b = put_in(options, [:depth], depth + 1) c = Noizu.RuleEngine.ScriptProtocol.render(this.argument, state, context, options_b) r = Enum.map(this.switch, fn({k,v}) -> Noizu.RuleEngine.ScriptProtocol.render(v && update_in(v, [Access.key(:identifier)], &("#{inspect k} #{inspect &1}")), state, context, options_b) end) """ #{prefix}#{identifier} [#{tag}] #{prefix} arg #{c} #{prefix} clauses #{Enum.join(r, "")} """ end end