From 90037af7380104a515823b826eac9f62f0fa5994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Thu, 16 Nov 2023 11:47:35 +0100 Subject: [PATCH] Message.merge unique flags / comments etc. --- lib/expo/message.ex | 41 ++++++++++++++++++++---------------- lib/expo/message/plural.ex | 35 +++++++++++++++++------------- lib/expo/message/singular.ex | 21 +++++++++++------- test/expo/message_test.exs | 27 ++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 41 deletions(-) diff --git a/lib/expo/message.ex b/lib/expo/message.ex index 885e410..2c41db6 100644 --- a/lib/expo/message.ex +++ b/lib/expo/message.ex @@ -115,9 +115,12 @@ 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) + + @spec raw_has_flag?([[String.t()]], String.t()) :: boolean() + 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`. @@ -132,19 +135,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 """ @@ -178,10 +183,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"]} diff --git a/lib/expo/message/plural.ex b/lib/expo/message/plural.ex index 36c1af6..b3e9023 100644 --- a/lib/expo/message/plural.ex +++ b/lib/expo/message/plural.ex @@ -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 diff --git a/lib/expo/message/singular.ex b/lib/expo/message/singular.ex index 0922775..1387257 100644 --- a/lib/expo/message/singular.ex +++ b/lib/expo/message/singular.ex @@ -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 diff --git a/test/expo/message_test.exs b/test/expo/message_test.exs index 28ca41d..c68a6d6 100644 --- a/test/expo/message_test.exs +++ b/test/expo/message_test.exs @@ -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