Skip to content

Commit 83abd38

Browse files
authored
feat: support IN operator for local evaluation (#33)
feat: support `IN` operator for local evaluation
2 parents ef3651d + 7ae0ef6 commit 83abd38

File tree

4 files changed

+34
-17
lines changed

4 files changed

+34
-17
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ flagsmith_engine-*.tar
2828
# Ignore the dialyzer PLTS
2929
/priv/plts
3030

31+
# ElixirLS
32+
.elixir_ls
33+
3134
.vscode/

lib/flagsmith_engine.ex

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -442,17 +442,8 @@ defmodule Flagsmith.Engine do
442442
trait_value: t_value
443443
} ->
444444
case prop == t_key do
445-
true ->
446-
case cast_value(t_value, value) do
447-
{:ok, casted} ->
448-
trait_match(operator, casted, t_value)
449-
450-
_ ->
451-
false
452-
end
453-
454-
_ ->
455-
false
445+
true -> trait_match(operator, value, t_value)
446+
_ -> false
456447
end
457448
end)
458449
end
@@ -580,10 +571,21 @@ defmodule Flagsmith.Engine do
580571
end
581572
end
582573

583-
def trait_match(:MODULO, trait, %Trait.Value{value: value}) do
584-
with true <- is_binary(trait),
574+
def trait_match(:IN, condition_value, %Trait.Value{type: :string, value: t_value}) do
575+
Enum.member?(String.split(condition_value, ","), t_value)
576+
end
577+
578+
def trait_match(:IN, condition_value, %Trait.Value{
579+
type: :decimal,
580+
value: %Decimal{exp: 0} = t_value
581+
}) do
582+
Enum.member?(String.split(condition_value, ","), t_value |> Decimal.to_string())
583+
end
584+
585+
def trait_match(:MODULO, condition_value, %Trait.Value{value: value}) do
586+
with true <- is_binary(condition_value),
585587
%Decimal{} <- value,
586-
[mod, result] <- String.split(trait, "|"),
588+
[mod, result] <- String.split(condition_value, "|"),
587589
%Decimal{} = mod_val <- Decimal.new(mod),
588590
%Decimal{} = result_val <- Decimal.new(result),
589591
%Decimal{} = remainder <- Decimal.rem(value, mod_val) do
@@ -595,7 +597,7 @@ defmodule Flagsmith.Engine do
595597
rescue
596598
Decimal.Error ->
597599
Logger.warn(
598-
"invalid MODULO segment rule or trait value :: rule: #{inspect(trait)} :: value: #{inspect(value)}"
600+
"invalid MODULO segment rule or trait value :: rule: #{inspect(condition_value)} :: value: #{inspect(value)}"
599601
)
600602

601603
false

lib/schemas/types/operator.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ defmodule Flagsmith.Schemas.Types.Operator do
1818
:IS_SET,
1919
:IS_NOT_SET,
2020
:MODULO,
21-
:PERCENTAGE_SPLIT
21+
:PERCENTAGE_SPLIT,
22+
:IN
2223
]
2324
end

test/unit/segment_conditions_test.exs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,18 @@ defmodule Flagsmith.Engine.SegmentConditionsTest do
6565
{:MODULO, "1.0.0", "3|0", false},
6666
{:MODULO, false, "1|3", false},
6767
{:MODULO, 3.5, "1.5|0.5", true},
68-
{:MODULO, 4, "1.5|0.5", false}
68+
{:MODULO, 4, "1.5|0.5", false},
69+
{:IN, "foo", "", false},
70+
{:IN, "foo", "foo,bar", true},
71+
{:IN, "bar", "foo,bar", true},
72+
{:IN, "ba", "foo,bar", false},
73+
{:IN, 1, "1,2,3,4", true},
74+
{:IN, 1, "", false},
75+
{:IN, 1, "1", true},
76+
# Flagsmith's engine does not evaluate `IN` condition for floats/doubles and booleans
77+
# due to ambiguous serialization across supported platforms.
78+
{:IN, 1.5, "1.5", false},
79+
{:IN, false, "false", false}
6980
]
7081

7182
test "all conditions" do

0 commit comments

Comments
 (0)