defmodule Condition do
defstruct [:path, :operator, :value]
end
defmodule ConditionSet do
defstruct [:all, :any]
end
defmodule Rule do
defstruct [:id, :conditions]
def new(%{"id"=>id, "conditions"=>conditions}) when is_map(conditions) do
%Rule{id: id, conditions: to_condition_or_set(conditions)}
end
defp to_condition_or_set(map_or_list) do
case map_or_list do
%{"path" => _path, "operator" => _operator, "value" => _value} ->
struct(Condition, map_or_list)
%{"all" => list} when is_list(list) ->
%ConditionSet{all: Enum.map(list, &to_condition_or_set(&1))}
%{"any" => list} when is_list(list) ->
%ConditionSet{any: Enum.map(list, &to_condition_or_set(&1))}
_ ->
raise ArgumentError, "invalid condition or set"
end
end
end
"""
example1 = %Rule{
id: "1",
conditions: %Condition{
path: "/operator_test",
operator: "equals",
value: "abc"
}
}
example2 = %Rule{
id: "2",
conditions: %ConditionSet{
all: [
%Condition{
path: "/operator_test",
operator: "equals",
value: "one"
},
%Condition{
path: "/path/0/test",
operator: "equals",
value: "two"
}
]
}
}
example3 = %Rule{
id: "3",
conditions: %ConditionSet{
any: [
%Condition{
path: "/path/0/test",
operator: "equals",
value: "one"
},
%Condition{
path: "/path/1/test",
operator: "equals",
value: "one"
}
]
}
}
example4 = %Rule{
id: "4",
conditions: %ConditionSet{
any: [
%Condition{
path: "/path/0/test",
operator: "equals",
value: "one"
},
%ConditionSet{
all: [
%Condition{
path: "/path/0/test",
operator: "equals",
value: "one"
},
%Condition{
path: "/path/1/test",
operator: "equals",
value: "two"
}
]
}
]
}
}
"""