Runic.Transmutable protocol (Runic v0.1.0-alpha.7)

Copy Markdown View Source

Protocol for converting data structures into Runic workflows or components.

The Transmutable protocol enables natural integration of domain-specific data structures into Runic workflows. Any data type that implements this protocol can be converted to a %Runic.Workflow{} or a Runic component (Step, Rule, etc.).

Protocol Functions

FunctionPurpose
transmute/1Deprecated - use to_workflow/1 instead
to_workflow/1Converts data to a %Runic.Workflow{}
to_component/1Converts data to a Runic component (Step, Rule, etc.)

Built-in Implementations

Typeto_workflow/1 Behaviorto_component/1 Behavior
Runic.WorkflowReturns itselfExtracts first component or raises
Runic.Workflow.RuleWraps rule in workflowReturns the rule
Runic.Workflow.StepWraps step in workflowReturns the step
Runic.Workflow.StateMachineWraps FSM in workflowReturns the FSM
FunctionCreates workflow with function as stepCreates Step wrapping the function
ListMerges transmuted elementsRecursively converts elements
Tuple (AST)Creates Rule from quoted functionCreates Rule from AST
AnyCreates workflow with constant stepCreates Step returning the value

Usage

require Runic
alias Runic.Transmutable

# Convert a function to workflow
fn_workflow = Transmutable.to_workflow(fn x -> x * 2 end)

# Convert a rule to workflow
rule = Runic.rule(fn x when x > 0 -> :positive end)
rule_workflow = Transmutable.to_workflow(rule)

# Convert a list of components to merged workflow
components = [
  Runic.step(fn x -> x + 1 end),
  Runic.step(fn x -> x * 2 end)
]
merged_workflow = Transmutable.to_workflow(components)

# Use the Runic.transmute/1 macro for convenient conversion
workflow = Runic.transmute(fn x -> x * 2 end)

Integration with Workflow.merge/2

The Transmutable protocol integrates with Workflow.merge/2:

workflow = Runic.Workflow.new()

# Merge a rule (transmuted to workflow first)
rule = Runic.rule(fn x when x > 0 -> :positive end)
workflow = Workflow.merge(workflow, rule)

# Merge a function directly
workflow = Workflow.merge(workflow, fn x -> x * 2 end)

Implementing Custom Transmutable

defmodule MyApp.DataProcessor do
  defstruct [:name, :transform_fn]
end

defimpl Runic.Transmutable, for: MyApp.DataProcessor do
  alias Runic.Workflow

  def transmute(processor), do: to_workflow(processor)

  def to_workflow(%MyApp.DataProcessor{} = processor) do
    step = Runic.Workflow.Step.new(
      work: processor.transform_fn,
      name: processor.name
    )

    Workflow.new(name: processor.name)
    |> Workflow.add_step(step)
    |> Map.put(:components, %{processor.name => processor})
  end

  def to_component(%MyApp.DataProcessor{} = processor) do
    Runic.Workflow.Step.new(
      work: processor.transform_fn,
      name: processor.name
    )
  end
end

See the Protocols Guide for more details and examples.

Summary

Types

t()

All the types that implement this protocol.

Functions

Converts user data to a Runic component.

Converts a component to a Runic Workflow.

DEPRECATED: Use to_workflow/1 instead. Converts a component to a Runic Workflow.

Types

t()

@type t() :: term()

All the types that implement this protocol.

Functions

to_component(component)

Converts user data to a Runic component.

to_workflow(component)

Converts a component to a Runic Workflow.

transmute(component)

DEPRECATED: Use to_workflow/1 instead. Converts a component to a Runic Workflow.