Skip to content

Commit

Permalink
Unique flags when merging messages (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
maennchen authored Nov 16, 2023
1 parent a6ed7f0 commit e317496
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 41 deletions.
40 changes: 22 additions & 18 deletions lib/expo/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ defmodule Expo.Message do
"""
@spec has_flag?(t(), String.t()) :: boolean()
def has_flag?(%mod{flags: flags} = _message, flag)
when mod in [Singular, Plural] and is_binary(flag) do
flag in List.flatten(flags)
end
when mod in [Singular, Plural] and is_binary(flag),
do: raw_has_flag?(flags, flag)

defp raw_has_flag?(flags, flag) when is_list(flags) when is_binary(flag),
do: flag in List.flatten(flags)

@doc """
Appends the given `flag` to the given `message`.
Expand All @@ -132,19 +134,21 @@ defmodule Expo.Message do
"""
@spec append_flag(t(), String.t()) :: t()
def append_flag(%mod{flags: flags} = message, flag) when mod in [Singular, Plural] do
flags =
if has_flag?(message, flag) do
flags
else
case flags do
[] -> [[flag]]
[flag_line] -> [flag_line ++ [flag]]
_multiple_lines -> flags ++ [[flag]]
end
def append_flag(%mod{flags: flags} = message, flag) when mod in [Singular, Plural],
do: struct!(message, flags: raw_append_flag(flags, flag))

@doc false
@spec raw_append_flag([[String.t()]], String.t()) :: [[String.t()]]
def raw_append_flag(flags, flag) when is_list(flags) when is_binary(flag) do
if raw_has_flag?(flags, flag) do
flags
else
case flags do
[] -> [[flag]]
[flag_line] -> [flag_line ++ [flag]]
_multiple_lines -> flags ++ [[flag]]
end

struct!(message, flags: flags)
end
end

@doc """
Expand Down Expand Up @@ -178,10 +182,10 @@ defmodule Expo.Message do
## Examples
iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: ["one"]}
...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: ["two"]}
iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: [["one"]]}
...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: [["one", "two"]]}
...> Expo.Message.merge(msg1, msg2)
%Expo.Message.Singular{msgid: ["test"], flags: ["one", "two"]}
%Expo.Message.Singular{msgid: ["test"], flags: [["one", "two"]]}
iex> msg1 = %Expo.Message.Singular{msgid: ["test"]}
...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["tests"]}
Expand Down
35 changes: 20 additions & 15 deletions lib/expo/message/plural.ex
Original file line number Diff line number Diff line change
Expand Up @@ -188,31 +188,36 @@ defmodule Expo.Message.Plural do
## Examples
iex> msg1 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["one"], flags: ["one"], msgstr: %{0 => "une"}}
...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: ["two"], msgstr: %{2 => "deux"}}
iex> msg1 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["one"], flags: [["one"]], msgstr: %{0 => "une"}}
...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: [["two"]], msgstr: %{2 => "deux"}}
...> Expo.Message.Plural.merge(msg1, msg2)
%Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: ["one", "two"], msgstr: %{0 => "une", 2 => "deux"}}
%Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: [["two", "one"]], msgstr: %{0 => "une", 2 => "deux"}}
"""
@doc since: "0.5.0"
@spec merge(t(), t()) :: t()
def merge(message1, message2) do
def merge(%__MODULE__{} = message1, %__MODULE__{} = message2) do
Map.merge(message1, message2, fn
key, value_1, value_2 when key in [:msgid, :msgid_plural] ->
if IO.iodata_length(value_2) > 0, do: value_2, else: value_1
key, value1, value2 when key in [:msgid, :msgid_plural] ->
if IO.iodata_length(value2) > 0, do: value2, else: value1

:msgctxt, _msgctxt_a, msgctxt_b ->
msgctxt_b
:msgctxt, _msgctxt1, msgctxt2 ->
msgctxt2

key, value_1, value_2
when key in [:comments, :extracted_comments, :flags, :previous_messages, :references] ->
Enum.concat(value_1, value_2)
:flags, flags1, flags2 ->
flags1
|> List.flatten()
|> Enum.reduce(flags2, &Message.raw_append_flag(&2, &1))

:msgstr, msgstr_a, msgstr_b ->
merge_msgstr(msgstr_a, msgstr_b)
key, value1, value2
when key in [:comments, :extracted_comments, :previous_messages, :references] ->
Enum.uniq(Enum.concat(value2, value1))

_key, _value_1, value_2 ->
value_2
:msgstr, msgstr1, msgstr2 ->
merge_msgstr(msgstr1, msgstr2)

_key, _value1, value2 ->
value2
end)
end

Expand Down
21 changes: 13 additions & 8 deletions lib/expo/message/singular.ex
Original file line number Diff line number Diff line change
Expand Up @@ -179,25 +179,30 @@ defmodule Expo.Message.Singular do
## Examples
iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: ["one"]}
...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: ["two"]}
iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: [["one"]]}
...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: [["two"]]}
...> Expo.Message.Singular.merge(msg1, msg2)
%Expo.Message.Singular{msgid: ["test"], flags: ["one", "two"]}
%Expo.Message.Singular{msgid: ["test"], flags: [["two", "one"]]}
"""
@doc since: "0.5.0"
@spec merge(t(), t()) :: t()
def merge(message1, message2) do
def merge(%__MODULE__{} = message1, %__MODULE__{} = message2) do
Map.merge(message1, message2, fn
key, value1, value2 when key in [:msgid, :msgstr] ->
if IO.iodata_length(value2) > 0, do: value2, else: value1

:msgctxt, _msgctxt_a, msgctxt_b ->
msgctxt_b
:msgctxt, _msgctxt1, msgctxt2 ->
msgctxt2

:flags, flags1, flags2 ->
flags1
|> List.flatten()
|> Enum.reduce(flags2, &Message.raw_append_flag(&2, &1))

key, value1, value2
when key in [:comments, :extracted_comments, :flags, :previous_messages, :references] ->
Enum.concat(value1, value2)
when key in [:comments, :extracted_comments, :previous_messages, :references] ->
Enum.uniq(Enum.concat(value1, value2))

_key, _value1, value2 ->
value2
Expand Down
27 changes: 27 additions & 0 deletions test/expo/message_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,31 @@ defmodule Expo.MessageTest do
assert %Message.Plural{flags: [["one"]]} = Message.append_flag(plural, "one")
end
end

describe "merge/2" do
test "merges messages" do
msg1 = %Message.Singular{
msgid: ["test"],
flags: [["one"], ["two"]],
comments: ["one", "two"],
msgstr: ["une"]
}

msg2 = %Message.Plural{
msgid: ["test"],
msgid_plural: ["two"],
flags: [["two"]],
comments: ["two"],
msgstr: %{2 => ["deux"]}
}

assert %Message.Plural{
msgid: ["test"],
msgid_plural: ["two"],
flags: [["two", "one"]],
comments: ["two", "one"],
msgstr: %{0 => ["une"], 2 => ["deux"]}
} = Message.merge(msg1, msg2)
end
end
end

0 comments on commit e317496

Please sign in to comment.