From 384b9b7a39d05238caffe915c72b6e51a8901f59 Mon Sep 17 00:00:00 2001 From: Danylo Negrienko Date: Tue, 14 May 2024 19:15:55 -0400 Subject: [PATCH] Added first non SEPA countries --- README.md | 4 +-- TODO.md | 56 ++++++++++++++++++++++++++++++ lib/iban_ex/country.ex | 38 ++++++++++++++++++-- lib/iban_ex/country/ad.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/ae.ex | 25 +++++++++++++ lib/iban_ex/country/al.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/az.ex | 25 +++++++++++++ lib/iban_ex/country/ba.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/bh.ex | 25 +++++++++++++ lib/iban_ex/country/br.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/ch.ex | 16 ++++++--- lib/iban_ex/country/cr.ex | 25 +++++++++++++ lib/iban_ex/country/cy.ex | 16 ++++++--- lib/iban_ex/country/cz.ex | 16 ++++++--- lib/iban_ex/country/de.ex | 16 ++++++--- lib/iban_ex/country/dk.ex | 16 ++++++--- lib/iban_ex/country/do.ex | 25 +++++++++++++ lib/iban_ex/country/ee.ex | 16 ++++++--- lib/iban_ex/country/eg.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/es.ex | 16 ++++++--- lib/iban_ex/country/fi.ex | 16 ++++++--- lib/iban_ex/country/fo.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/fr.ex | 16 ++++++--- lib/iban_ex/country/gb.ex | 16 ++++++--- lib/iban_ex/country/ge.ex | 25 +++++++++++++ lib/iban_ex/country/gi.ex | 16 ++++++--- lib/iban_ex/country/gl.ex | 25 +++++++++++++ lib/iban_ex/country/gr.ex | 16 ++++++--- lib/iban_ex/country/gt.ex | 25 +++++++++++++ lib/iban_ex/country/hr.ex | 16 ++++++--- lib/iban_ex/country/hu.ex | 16 ++++++--- lib/iban_ex/country/ie.ex | 16 ++++++--- lib/iban_ex/country/il.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/it.ex | 16 ++++++--- lib/iban_ex/country/jo.ex | 42 ++++++++++++++++++++++ lib/iban_ex/country/kw.ex | 25 +++++++++++++ lib/iban_ex/country/kz.ex | 25 +++++++++++++ lib/iban_ex/country/lb.ex | 25 +++++++++++++ lib/iban_ex/country/li.ex | 16 ++++++--- lib/iban_ex/country/lt.ex | 16 ++++++--- lib/iban_ex/country/lu.ex | 16 ++++++--- lib/iban_ex/country/lv.ex | 16 ++++++--- lib/iban_ex/country/mc.ex | 16 ++++++--- lib/iban_ex/country/md.ex | 25 +++++++++++++ lib/iban_ex/country/me.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/mk.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/mr.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/mt.ex | 16 ++++++--- lib/iban_ex/country/nl.ex | 16 ++++++--- lib/iban_ex/country/no.ex | 16 ++++++--- lib/iban_ex/country/pk.ex | 25 +++++++++++++ lib/iban_ex/country/pl.ex | 16 ++++++--- lib/iban_ex/country/pt.ex | 16 ++++++--- lib/iban_ex/country/qa.ex | 25 +++++++++++++ lib/iban_ex/country/ro.ex | 16 ++++++--- lib/iban_ex/country/rs.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/sa.ex | 25 +++++++++++++ lib/iban_ex/country/se.ex | 16 ++++++--- lib/iban_ex/country/si.ex | 16 ++++++--- lib/iban_ex/country/sk.ex | 16 ++++++--- lib/iban_ex/country/sm.ex | 16 ++++++--- lib/iban_ex/country/sv.ex | 25 +++++++++++++ lib/iban_ex/country/template.ex | 2 +- lib/iban_ex/country/tl.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/tr.ex | 43 +++++++++++++++++++++++ lib/iban_ex/country/ua.ex | 16 ++++++--- lib/iban_ex/country/va.ex | 16 ++++++--- lib/iban_ex/country/vg.ex | 25 +++++++++++++ lib/iban_ex/country/xk.ex | 43 +++++++++++++++++++++++ lib/iban_ex/deserialize.ex | 39 +++++++++++++++------ lib/iban_ex/parser.ex | 13 +++++-- lib/iban_ex/serialize.ex | 2 +- lib/iban_ex/validator/validator.ex | 42 +++++++++++++--------- mix.exs | 2 +- test/iban_ex_test.exs | 34 +++++++++++++++++- 75 files changed, 1653 insertions(+), 170 deletions(-) create mode 100644 TODO.md create mode 100644 lib/iban_ex/country/ad.ex create mode 100644 lib/iban_ex/country/ae.ex create mode 100644 lib/iban_ex/country/al.ex create mode 100644 lib/iban_ex/country/az.ex create mode 100644 lib/iban_ex/country/ba.ex create mode 100644 lib/iban_ex/country/bh.ex create mode 100644 lib/iban_ex/country/br.ex create mode 100644 lib/iban_ex/country/cr.ex create mode 100644 lib/iban_ex/country/do.ex create mode 100644 lib/iban_ex/country/eg.ex create mode 100644 lib/iban_ex/country/fo.ex create mode 100644 lib/iban_ex/country/ge.ex create mode 100644 lib/iban_ex/country/gl.ex create mode 100644 lib/iban_ex/country/gt.ex create mode 100644 lib/iban_ex/country/il.ex create mode 100644 lib/iban_ex/country/jo.ex create mode 100644 lib/iban_ex/country/kw.ex create mode 100644 lib/iban_ex/country/kz.ex create mode 100644 lib/iban_ex/country/lb.ex create mode 100644 lib/iban_ex/country/md.ex create mode 100644 lib/iban_ex/country/me.ex create mode 100644 lib/iban_ex/country/mk.ex create mode 100644 lib/iban_ex/country/mr.ex create mode 100644 lib/iban_ex/country/pk.ex create mode 100644 lib/iban_ex/country/qa.ex create mode 100644 lib/iban_ex/country/rs.ex create mode 100644 lib/iban_ex/country/sa.ex create mode 100644 lib/iban_ex/country/sv.ex create mode 100644 lib/iban_ex/country/tl.ex create mode 100644 lib/iban_ex/country/tr.ex create mode 100644 lib/iban_ex/country/vg.ex create mode 100644 lib/iban_ex/country/xk.ex diff --git a/README.md b/README.md index f060494..1b2c65d 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ In just a few letters and numbers, the IBAN captures all of the country, bank, a #### To check IBAN's country is supported ```elixir - iex> {:error, unsupported_country_code} = IbanEx.Parser.parse("AZ21NABZ00000000137010001944") + iex> {:error, unsupported_country_code} = IbanEx.Parser.parse("ZU21NABZ00000000137010001944") {:error, :unsupported_country_code} iex> IbanEx.Error.message(unsupported_country_code) "Unsupported country code" @@ -71,7 +71,7 @@ The package can be installed by adding `iban_ex` to your list of dependencies in ```elixir def deps do [ - {:iban_ex, "~> 0.1.5"} + {:iban_ex, "~> 0.1.6"} ] end ``` diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..4173d3d --- /dev/null +++ b/TODO.md @@ -0,0 +1,56 @@ +TODO Check Regexes and add unsupported now countries + +```elixir +"AA" => %{length: 16, rule: ~r/^[0-9A-Z]{12}$/i}, +"AO" => %{length: 25, rule: ~r/^[0-9]{21}$/i}, +"AX" => %{length: 18, rule: ~r/^[0-9]{14}$/i}, +"BF" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"BI" => %{length: 16, rule: ~r/^[0-9]{12}$/i}, +"BJ" => %{length: 28, rule: ~r/^[A-Z]{1}[0-9]{23}$/i}, +"BL" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"BY" => %{length: 28, rule: ~r/^[0-9A-Z]{4}[0-9]{4}[0-9A-Z]{16}$/i}, +"CF" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"CG" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"CI" => %{length: 28, rule: ~r/^[A-Z]{1}[0-9]{23}$/i}, +"CM" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"CV" => %{length: 25, rule: ~r/^[0-9]{21}$/i}, +"DJ" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"DZ" => %{length: 24, rule: ~r/^[0-9]{20}$/i}, +"GA" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"GF" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"GP" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"GQ" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"GW" => %{length: 25, rule: ~r/^[0-9A-Z]{2}[0-9]{19}$/i}, +"HN" => %{length: 28, rule: ~r/^[A-Z]{4}[0-9]{20}$/i}, +"IE" => %{length: 22, rule: ~r/^[A-Z]{4}[0-9]{14}$/i}, +"IQ" => %{length: 23, rule: ~r/^[0-9A-Z]{4}[0-9]{15}$/i}, +"IR" => %{length: 26, rule: ~r/^[0-9]{22}$/i}, +"IS" => %{length: 26, rule: ~r/^[0-9]{22}$/i}, +"KM" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"LC" => %{length: 32, rule: ~r/^[A-Z]{4}[0-9A-Z]{24}$/i}, +"MA" => %{length: 28, rule: ~r/^[0-9]{24}$/i}, +"MF" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"MG" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"MK" => %{length: 19, rule: ~r/^[0-9]{3}[0-9A-Z]{10}[0-9]{2}$/i}, +"ML" => %{length: 28, rule: ~r/^[A-Z]{1}[0-9]{23}$/i}, +"MQ" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"MU" => %{length: 30, rule: ~r/^[A-Z]{4}[0-9]{19}[A-Z]{3}$/i}, +"MZ" => %{length: 25, rule: ~r/^[0-9]{21}$/i}, +"NC" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"NE" => %{length: 28, rule: ~r/^[A-Z]{2}[0-9]{22}$/i}, +"NI" => %{length: 32, rule: ~r/^[A-Z]{4}[0-9]{24}$/i}, +"PF" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"PM" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"PS" => %{length: 29, rule: ~r/^[A-Z]{4}[0-9A-Z]{21}$/i}, +"QA" => %{length: 29, rule: ~r/^[A-Z]{4}[0-9]{4}[0-9A-Z]{17}$/i}, +"RE" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"SC" => %{length: 31, rule: ~r/^[A-Z]{4}[0-9]{20}[A-Z]{3}$/i}, +"SN" => %{length: 28, rule: ~r/^[A-Z]{1}[0-9]{23}$/i}, +"ST" => %{length: 25, rule: ~r/^[0-9]{8}[0-9]{13}$/i}, +"TD" => %{length: 27, rule: ~r/^[0-9]{23}$/i}, +"TF" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"TG" => %{length: 28, rule: ~r/^[A-Z]{2}[0-9]{22}$/i}, +"TN" => %{length: 24, rule: ~r/^[0-9]{20}$/i}, +"WF" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i}, +"YT" => %{length: 27, rule: ~r/^[0-9]{10}[0-9A-Z]{11}[0-9]{2}$/i} +``` \ No newline at end of file diff --git a/lib/iban_ex/country.ex b/lib/iban_ex/country.ex index 301df0e..34fc842 100644 --- a/lib/iban_ex/country.ex +++ b/lib/iban_ex/country.ex @@ -7,42 +7,74 @@ defmodule IbanEx.Country do @type error_tuple() :: {:error, atom()} @supported_countries %{ + "AD" => IbanEx.Country.AD, + "AE" => IbanEx.Country.AE, + "AL" => IbanEx.Country.AL, "AT" => IbanEx.Country.AT, + "AZ" => IbanEx.Country.AZ, + "BA" => IbanEx.Country.BA, "BE" => IbanEx.Country.BE, "BG" => IbanEx.Country.BG, + "BH" => IbanEx.Country.BH, + "BR" => IbanEx.Country.BR, "CH" => IbanEx.Country.CH, + "CR" => IbanEx.Country.CR, "CY" => IbanEx.Country.CY, "CZ" => IbanEx.Country.CZ, "DE" => IbanEx.Country.DE, + "DO" => IbanEx.Country.DO, "DK" => IbanEx.Country.DK, "EE" => IbanEx.Country.EE, "ES" => IbanEx.Country.ES, + "EG" => IbanEx.Country.EG, "FI" => IbanEx.Country.FI, "FR" => IbanEx.Country.FR, + "FO" => IbanEx.Country.FO, "GB" => IbanEx.Country.GB, + "GE" => IbanEx.Country.GE, "GI" => IbanEx.Country.GI, + "GL" => IbanEx.Country.GL, "GR" => IbanEx.Country.GR, + "GT" => IbanEx.Country.GT, "HR" => IbanEx.Country.HR, "HU" => IbanEx.Country.HU, "IE" => IbanEx.Country.IE, + "IL" => IbanEx.Country.IL, "IT" => IbanEx.Country.IT, + "JO" => IbanEx.Country.JO, + "KZ" => IbanEx.Country.KZ, + "KW" => IbanEx.Country.KW, + "LB" => IbanEx.Country.LB, "LI" => IbanEx.Country.LI, "LT" => IbanEx.Country.LT, "LU" => IbanEx.Country.LU, "LV" => IbanEx.Country.LV, "MC" => IbanEx.Country.MC, + "MD" => IbanEx.Country.MD, + "ME" => IbanEx.Country.ME, + "MK" => IbanEx.Country.MK, + "MR" => IbanEx.Country.MR, "MT" => IbanEx.Country.MT, "NL" => IbanEx.Country.NL, "NO" => IbanEx.Country.NO, "PL" => IbanEx.Country.PL, "PT" => IbanEx.Country.PT, + "PK" => IbanEx.Country.PK, + "QA" => IbanEx.Country.QA, "RO" => IbanEx.Country.RO, + "RS" => IbanEx.Country.RS, + "SA" => IbanEx.Country.SA, "SE" => IbanEx.Country.SE, - "SM" => IbanEx.Country.SM, "SI" => IbanEx.Country.SI, "SK" => IbanEx.Country.SK, + "SM" => IbanEx.Country.SM, + "SV" => IbanEx.Country.SV, + "TL" => IbanEx.Country.TL, + "TR" => IbanEx.Country.TR, "UA" => IbanEx.Country.UA, - "VA" => IbanEx.Country.VA + "VA" => IbanEx.Country.VA, + "VG" => IbanEx.Country.VG, + "XK" => IbanEx.Country.XK } @supported_country_codes Map.keys(@supported_countries) @@ -57,7 +89,7 @@ defmodule IbanEx.Country do @spec supported_country_modules() :: [module()] | [] def supported_country_modules(), do: @supported_country_modules - @spec country_module(country_code) :: Module.t() | error_tuple() + @spec country_module(country_code) :: module() | error_tuple() def country_module(country_code) when is_binary(country_code) or is_atom(country_code) do normalized_country_code = normalize(country_code) case is_country_code_supported?(normalized_country_code) do diff --git a/lib/iban_ex/country/ad.ex b/lib/iban_ex/country/ad.ex new file mode 100644 index 0000000..d32462c --- /dev/null +++ b/lib/iban_ex/country/ad.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.AD do + @moduledoc """ + Andorra IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "AD", + ...> check_digits: "12", + ...> bank_code: "0001", + ...> branch_code: "2030", + ...> national_check: nil, + ...> account_number: "200359100100" + ...> } + ...> |> IbanEx.Country.AD.to_string() + "AD 12 0001 2030 200359100100" + ``` + """ + + @size 24 + @rule ~r/^(?[0-9]{4})(?[0-9]{4})(?[0-9A-Z]{12})$/i + + use IbanEx.Country.Template + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: _national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/ae.ex b/lib/iban_ex/country/ae.ex new file mode 100644 index 0000000..ac20be4 --- /dev/null +++ b/lib/iban_ex/country/ae.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.AE do + @moduledoc """ + United Arab Emirates IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "AE", + ...> check_digits: "07", + ...> bank_code: "033", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "1234567890123456" + ...> } + ...> |> IbanEx.Country.AE.to_string() + "AE 07 033 1234567890123456" + ``` + """ + + @size 23 + @rule ~r/^(?[0-9]{3})(?[0-9]{16})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/al.ex b/lib/iban_ex/country/al.ex new file mode 100644 index 0000000..0e8e2d9 --- /dev/null +++ b/lib/iban_ex/country/al.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.AL do + @moduledoc """ + Albania IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "AL", + ...> check_digits: "47", + ...> bank_code: "212", + ...> branch_code: "1100", + ...> national_check: "9", + ...> account_number: "0000000235698741" + ...> } + ...> |> IbanEx.Country.AL.to_string() + "AL 47 212 1100 9 0000000235698741" + ``` + """ + + @size 28 + @rule ~r/^(?[0-9]{3})(?[0-9]{4})(?[0-9]{1})(?[0-9A-Z]{16})$/i + + use IbanEx.Country.Template + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, national_check, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/az.ex b/lib/iban_ex/country/az.ex new file mode 100644 index 0000000..1f56383 --- /dev/null +++ b/lib/iban_ex/country/az.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.AZ do + @moduledoc """ + Azerbaijan IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "AZ", + ...> check_digits: "21", + ...> bank_code: "NABZ", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00000000137010001944" + ...> } + ...> |> IbanEx.Country.AZ.to_string() + "AZ 21 NABZ 00000000137010001944" + ``` + """ + + @size 28 + @rule ~r/^(?[A-Z]{4})(?[0-9A-Z]{20})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/ba.ex b/lib/iban_ex/country/ba.ex new file mode 100644 index 0000000..467461c --- /dev/null +++ b/lib/iban_ex/country/ba.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.BA do + @moduledoc """ + Bosnia and Herzegovina IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "BA", + ...> check_digits: "39", + ...> bank_code: "129", + ...> branch_code: "007", + ...> national_check: "94", + ...> account_number: "94010284" + ...> } + ...> |> IbanEx.Country.BA.to_string() + "BA 39 129 007 94010284 94" + ``` + """ + + @size 20 + @rule ~r/^(?[0-9]{3})(?[0-9]{3})(?[0-9]{8})(?[0-9]{2})$/i + + use IbanEx.Country.Template + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/bh.ex b/lib/iban_ex/country/bh.ex new file mode 100644 index 0000000..3d36ac0 --- /dev/null +++ b/lib/iban_ex/country/bh.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.BH do + @moduledoc """ + Bahrain IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "BH", + ...> check_digits: "67", + ...> bank_code: "BMAG", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00001299123456" + ...> } + ...> |> IbanEx.Country.BH.to_string() + "BH 67 BMAG 00001299123456" + ``` + """ + + @size 22 + @rule ~r/^(?[A-Z]{4})(?[0-9]{14})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/br.ex b/lib/iban_ex/country/br.ex new file mode 100644 index 0000000..8e1cd88 --- /dev/null +++ b/lib/iban_ex/country/br.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.BR do + @moduledoc """ + Brazil IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "BR", + ...> check_digits: "18", + ...> bank_code: "00360305", + ...> branch_code: "00001", + ...> account_number: "0009795493", + ...> national_check: "C1" + ...> } + ...> |> IbanEx.Country.BR.to_string() + "BR 18 00360305 00001 0009795493 C1" + ``` + """ + + @size 29 + @rule ~r/^(?[0-9]{8})(?[0-9]{5})(?[0-9]{10})(?[A-Z]{1}[0-9A-Z]{1})$/i + + use IbanEx.Country.Template + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + account_number: account_number, + national_check: national_check + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/ch.ex b/lib/iban_ex/country/ch.ex index c071513..74299d4 100644 --- a/lib/iban_ex/country/ch.ex +++ b/lib/iban_ex/country/ch.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.CH do ## Examples - iex> %IbanEx.Iban{country_code: "CH", check_digits: "93", bank_code: "00762", branch_code: nil, national_check: nil, account_number: "011623852957"} - iex> |> IbanEx.Country.CH.to_string() - "CH 93 00762 011623852957" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "CH", + ...> check_digits: "93", + ...> bank_code: "00762", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "011623852957" + ...> } + ...> |> IbanEx.Country.CH.to_string() + "CH 93 00762 011623852957" + ``` """ @size 21 diff --git a/lib/iban_ex/country/cr.ex b/lib/iban_ex/country/cr.ex new file mode 100644 index 0000000..54873c2 --- /dev/null +++ b/lib/iban_ex/country/cr.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.CR do + @moduledoc """ + Costa Rica IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "CR", + ...> check_digits: "05", + ...> bank_code: "0152", + ...> branch_code: nil, + ...> account_number: "02001026284066", + ...> national_check: nil + ...> } + ...> |> IbanEx.Country.CR.to_string() + "CR 05 0152 02001026284066" + ``` + """ + + @size 22 + @rule ~r/^(?[0-9]{4})(?[0-9]{14})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/cy.ex b/lib/iban_ex/country/cy.ex index 5387061..aec9d6b 100644 --- a/lib/iban_ex/country/cy.ex +++ b/lib/iban_ex/country/cy.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.CY do ## Examples - iex> %IbanEx.Iban{country_code: "CY", check_digits: "17", bank_code: "002", branch_code: "00128", national_check: nil, account_number: "0000001200527600"} - iex> |> IbanEx.Country.CY.to_string() - "CY 17 002 00128 0000001200527600" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "CY", + ...> check_digits: "17", + ...> bank_code: "002", + ...> branch_code: "00128", + ...> national_check: nil, + ...> account_number: "0000001200527600" + ...> } + ...> |> IbanEx.Country.CY.to_string() + "CY 17 002 00128 0000001200527600" + ``` """ @size 28 diff --git a/lib/iban_ex/country/cz.ex b/lib/iban_ex/country/cz.ex index 21f8aa5..0869649 100644 --- a/lib/iban_ex/country/cz.ex +++ b/lib/iban_ex/country/cz.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.CZ do ## Examples - iex> %IbanEx.Iban{country_code: "CZ", check_digits: "65", bank_code: "0800", branch_code: nil, national_check: nil, account_number: "0000192000145399"} - iex> |> IbanEx.Country.CZ.to_string() - "CZ 65 0800 0000192000145399" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "CZ", + ...> check_digits: "65", + ...> bank_code: "0800", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000192000145399" + ...> } + ...> |> IbanEx.Country.CZ.to_string() + "CZ 65 0800 0000192000145399" + ``` """ @size 24 diff --git a/lib/iban_ex/country/de.ex b/lib/iban_ex/country/de.ex index 7a71b31..cf17ff2 100644 --- a/lib/iban_ex/country/de.ex +++ b/lib/iban_ex/country/de.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.DE do ## Examples - iex> %IbanEx.Iban{country_code: "DE", check_digits: "89", bank_code: "37040044", branch_code: nil, national_check: nil, account_number: "0532013000"} - iex> |> IbanEx.Country.DE.to_string() - "DE 89 37040044 0532013000" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "DE", + ...> check_digits: "89", + ...> bank_code: "37040044", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0532013000" + ...> } + ...> |> IbanEx.Country.DE.to_string() + "DE 89 37040044 0532013000" + ``` """ @size 22 diff --git a/lib/iban_ex/country/dk.ex b/lib/iban_ex/country/dk.ex index d218de2..ae17c92 100644 --- a/lib/iban_ex/country/dk.ex +++ b/lib/iban_ex/country/dk.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.DK do ## Examples - iex> %IbanEx.Iban{country_code: "DK", check_digits: "50", bank_code: "0040", branch_code: nil, national_check: nil, account_number: "0440116243"} - iex> |> IbanEx.Country.DK.to_string() - "DK 50 0040 0440116243" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "DK", + ...> check_digits: "50", + ...> bank_code: "0040", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0440116243" + ...> } + ...> |> IbanEx.Country.DK.to_string() + "DK 50 0040 0440116243" + ``` """ @size 18 @rule ~r/^(?[0-9]{4})(?[0-9]{10})$/i diff --git a/lib/iban_ex/country/do.ex b/lib/iban_ex/country/do.ex new file mode 100644 index 0000000..9163ce4 --- /dev/null +++ b/lib/iban_ex/country/do.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.DO do + @moduledoc """ + Dominican Republic IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "DO", + ...> check_digits: "28", + ...> bank_code: "BAGR", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00000001212453611324" + ...> } + ...> |> IbanEx.Country.DO.to_string() + "DO 28 BAGR 00000001212453611324" + ``` + """ + + @size 28 + @rule ~r/^(?[0-9A-Z]{4})(?[0-9]{20})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/ee.ex b/lib/iban_ex/country/ee.ex index 0779353..b23ad96 100644 --- a/lib/iban_ex/country/ee.ex +++ b/lib/iban_ex/country/ee.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.EE do ## Examples - iex> %IbanEx.Iban{country_code: "EE", check_digits: "38", bank_code: "22", branch_code: "00", national_check: "5", account_number: "22102014568"} - iex> |> IbanEx.Country.EE.to_string() - "EE 38 22 00 22102014568 5" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "EE", + ...> check_digits: "38", + ...> bank_code: "22", + ...> branch_code: "00", + ...> national_check: "5", + ...> account_number: "22102014568" + ...> } + ...> |> IbanEx.Country.EE.to_string() + "EE 38 22 00 22102014568 5" + ``` """ @size 20 diff --git a/lib/iban_ex/country/eg.ex b/lib/iban_ex/country/eg.ex new file mode 100644 index 0000000..2e178ca --- /dev/null +++ b/lib/iban_ex/country/eg.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.EG do + @moduledoc """ + Egypt IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "EG", + ...> check_digits: "38", + ...> bank_code: "0019", + ...> branch_code: "0005", + ...> national_check: nil, + ...> account_number: "00000000263180002" + ...> } + ...> |> IbanEx.Country.EG.to_string() + "EG 38 0019 0005 00000000263180002" + ``` + """ + + @size 29 + @rule ~r/^(?[0-9]{4})(?[0-9]{4})(?[0-9]{17})$/i + + use IbanEx.Country.Template + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: _national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/es.ex b/lib/iban_ex/country/es.ex index cca4b58..ae994cd 100644 --- a/lib/iban_ex/country/es.ex +++ b/lib/iban_ex/country/es.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.ES do ## Examples - iex> %IbanEx.Iban{country_code: "ES", check_digits: "91", bank_code: "2100", branch_code: "0418", national_check: "45", account_number: "0200051332"} - iex> |> IbanEx.Country.ES.to_string() - "ES 91 2100 0418 45 0200051332" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "ES", + ...> check_digits: "91", + ...> bank_code: "2100", + ...> branch_code: "0418", + ...> national_check: "45", + ...> account_number: "0200051332" + ...> } + ...> |> IbanEx.Country.ES.to_string() + "ES 91 2100 0418 45 0200051332" + ``` """ @size 24 diff --git a/lib/iban_ex/country/fi.ex b/lib/iban_ex/country/fi.ex index 5e3be14..a5f9c8f 100644 --- a/lib/iban_ex/country/fi.ex +++ b/lib/iban_ex/country/fi.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.FI do ## Examples - iex> %IbanEx.Iban{country_code: "FI", check_digits: "21", bank_code: "123456", branch_code: nil, national_check: "5", account_number: "0000078"} - iex> |> IbanEx.Country.FI.to_string() - "FI 21 123456 0000078 5" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "FI", + ...> check_digits: "21", + ...> bank_code: "123456", + ...> branch_code: nil, + ...> national_check: "5", + ...> account_number: "0000078" + ...> } + ...> |> IbanEx.Country.FI.to_string() + "FI 21 123456 0000078 5" + ``` """ @size 18 diff --git a/lib/iban_ex/country/fo.ex b/lib/iban_ex/country/fo.ex new file mode 100644 index 0000000..a3f0fc9 --- /dev/null +++ b/lib/iban_ex/country/fo.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.FO do + @moduledoc """ + Faroe Islands IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "FO", + ...> check_digits: "62", + ...> bank_code: "6460", + ...> branch_code: nil, + ...> national_check: "4", + ...> account_number: "000163163" + ...> } + ...> |> IbanEx.Country.FO.to_string() + "FO 62 6460 000163163 4" + ``` + """ + + @size 18 + @rule ~r/^(?[0-9]{4})(?[0-9]{9})(?[0-9]{1})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/fr.ex b/lib/iban_ex/country/fr.ex index 758fe6e..f3473a1 100644 --- a/lib/iban_ex/country/fr.ex +++ b/lib/iban_ex/country/fr.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.FR do ## Examples - iex> %IbanEx.Iban{country_code: "FR", check_digits: "14", bank_code: "20041", branch_code: "01005", national_check: "06", account_number: "0500013M026"} - iex> |> IbanEx.Country.FR.to_string() - "FR 14 20041 01005 0500013M026 06" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "FR", + ...> check_digits: "14", + ...> bank_code: "20041", + ...> branch_code: "01005", + ...> national_check: "06", + ...> account_number: "0500013M026" + ...> } + ...> |> IbanEx.Country.FR.to_string() + "FR 14 20041 01005 0500013M026 06" + ``` """ @size 27 diff --git a/lib/iban_ex/country/gb.ex b/lib/iban_ex/country/gb.ex index 56f9029..500ecb5 100644 --- a/lib/iban_ex/country/gb.ex +++ b/lib/iban_ex/country/gb.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.GB do ## Examples - iex> %IbanEx.Iban{country_code: "GB", check_digits: "29", bank_code: "NWBK", branch_code: "601613", national_check: "06", account_number: "31926819"} - iex> |> IbanEx.Country.GB.to_string() - "GB 29 NWBK 601613 31926819" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GB", + ...> check_digits: "29", + ...> bank_code: "NWBK", + ...> branch_code: "601613", + ...> national_check: "06", + ...> account_number: "31926819" + ...> } + ...> |> IbanEx.Country.GB.to_string() + "GB 29 NWBK 601613 31926819" + ``` """ @size 22 diff --git a/lib/iban_ex/country/ge.ex b/lib/iban_ex/country/ge.ex new file mode 100644 index 0000000..6e1b09a --- /dev/null +++ b/lib/iban_ex/country/ge.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.GE do + @moduledoc """ + Georgia IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GE", + ...> check_digits: "29", + ...> bank_code: "NB", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000000101904917" + ...> } + ...> |> IbanEx.Country.GE.to_string() + "GE 29 NB 0000000101904917" + ``` + """ + + @size 22 + @rule ~r/^(?[A-Z]{2})(?[0-9]{16})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/gi.ex b/lib/iban_ex/country/gi.ex index f537693..6ceb3df 100644 --- a/lib/iban_ex/country/gi.ex +++ b/lib/iban_ex/country/gi.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.GI do ## Examples - iex> %IbanEx.Iban{country_code: "GI", check_digits: "75", bank_code: "NWBK", branch_code: nil, national_check: nil, account_number: "000000007099453"} - iex> |> IbanEx.Country.GI.to_string() - "GI 75 NWBK 000000007099453" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GI", + ...> check_digits: "75", + ...> bank_code: "NWBK", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "000000007099453" + ...> } + ...> |> IbanEx.Country.GI.to_string() + "GI 75 NWBK 000000007099453" + ``` """ @size 23 diff --git a/lib/iban_ex/country/gl.ex b/lib/iban_ex/country/gl.ex new file mode 100644 index 0000000..8d41ba1 --- /dev/null +++ b/lib/iban_ex/country/gl.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.GL do + @moduledoc """ + Greenland IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GL", + ...> check_digits: "89", + ...> bank_code: "6471", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0001000206" + ...> } + ...> |> IbanEx.Country.GL.to_string() + "GL 89 6471 0001000206" + ``` + """ + + @size 18 + @rule ~r/^(?[0-9]{4})(?[0-9]{10})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/gr.ex b/lib/iban_ex/country/gr.ex index 3675de8..c8f69b4 100644 --- a/lib/iban_ex/country/gr.ex +++ b/lib/iban_ex/country/gr.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.GR do ## Examples - iex> %IbanEx.Iban{country_code: "GR", check_digits: "16", bank_code: "011", branch_code: "0125", national_check: nil, account_number: "0000000012300695"} - iex> |> IbanEx.Country.GR.to_string() - "GR 16 011 0125 0000000012300695" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GR", + ...> check_digits: "16", + ...> bank_code: "011", + ...> branch_code: "0125", + ...> national_check: nil, + ...> account_number: "0000000012300695" + ...> } + ...> |> IbanEx.Country.GR.to_string() + "GR 16 011 0125 0000000012300695" + ``` """ @size 27 diff --git a/lib/iban_ex/country/gt.ex b/lib/iban_ex/country/gt.ex new file mode 100644 index 0000000..cd9c6f8 --- /dev/null +++ b/lib/iban_ex/country/gt.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.GT do + @moduledoc """ + Guatemala IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "GT", + ...> check_digits: "82", + ...> bank_code: "TRAJ", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "01020000001210029690" + ...> } + ...> |> IbanEx.Country.GT.to_string() + "GT 82 TRAJ 01020000001210029690" + ``` + """ + + @size 28 + @rule ~r/^(?[A-Z]{4})(?[0-9]{20})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/hr.ex b/lib/iban_ex/country/hr.ex index 7bffba8..67f06a8 100644 --- a/lib/iban_ex/country/hr.ex +++ b/lib/iban_ex/country/hr.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.HR do ## Examples - iex> %IbanEx.Iban{country_code: "HR", check_digits: "12", bank_code: "1001005", branch_code: nil, national_check: nil, account_number: "1863000160"} - iex> |> IbanEx.Country.HR.to_string() - "HR 12 1001005 1863000160" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "HR", + ...> check_digits: "12", + ...> bank_code: "1001005", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "1863000160" + ...> } + ...> |> IbanEx.Country.HR.to_string() + "HR 12 1001005 1863000160" + ``` """ @size 21 diff --git a/lib/iban_ex/country/hu.ex b/lib/iban_ex/country/hu.ex index fa3da3a..6f396e3 100644 --- a/lib/iban_ex/country/hu.ex +++ b/lib/iban_ex/country/hu.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.HU do ## Examples - iex> %IbanEx.Iban{country_code: "HU", check_digits: "42", bank_code: "117", branch_code: "7301", national_check: "0", account_number: "6111110180000000"} - iex> |> IbanEx.Country.HU.to_string() - "HU 42 117 7301 6111110180000000 0" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "HU", + ...> check_digits: "42", + ...> bank_code: "117", + ...> branch_code: "7301", + ...> national_check: "0", + ...> account_number: "6111110180000000" + ...> } + ...> |> IbanEx.Country.HU.to_string() + "HU 42 117 7301 6111110180000000 0" + ``` """ @size 28 diff --git a/lib/iban_ex/country/ie.ex b/lib/iban_ex/country/ie.ex index 3f08a4c..b72c408 100644 --- a/lib/iban_ex/country/ie.ex +++ b/lib/iban_ex/country/ie.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.IE do ## Examples - iex> %IbanEx.Iban{country_code: "IE", check_digits: "29", bank_code: "AIBK", branch_code: "931152", national_check: nil, account_number: "12345678"} - iex> |> IbanEx.Country.IE.to_string() - "IE 29 AIBK 931152 12345678" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "IE", + ...> check_digits: "29", + ...> bank_code: "AIBK", + ...> branch_code: "931152", + ...> national_check: nil, + ...> account_number: "12345678" + ...> } + ...> |> IbanEx.Country.IE.to_string() + "IE 29 AIBK 931152 12345678" + ``` """ @size 22 diff --git a/lib/iban_ex/country/il.ex b/lib/iban_ex/country/il.ex new file mode 100644 index 0000000..2dbadf5 --- /dev/null +++ b/lib/iban_ex/country/il.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.IL do + @moduledoc """ + Israel IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "IL", + ...> check_digits: "62", + ...> bank_code: "010", + ...> branch_code: "800", + ...> national_check: nil, + ...> account_number: "0000099999999" + ...> } + ...> |> IbanEx.Country.IL.to_string() + "IL 62 010 800 0000099999999" + ``` + """ + + @size 23 + @rule ~r/^(?[0-9]{3})(?[0-9]{3})(?[0-9]{13})$/i + + use IbanEx.Country.Template + + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: _national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/it.ex b/lib/iban_ex/country/it.ex index aebaabb..f18ba64 100644 --- a/lib/iban_ex/country/it.ex +++ b/lib/iban_ex/country/it.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.IT do ## Examples - iex> %IbanEx.Iban{country_code: "IT", check_digits: "60", bank_code: "05428", branch_code: "11101", national_check: "X", account_number: "000000123456"} - iex> |> IbanEx.Country.IT.to_string() - "IT 60 X 05428 11101 000000123456" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "IT", + ...> check_digits: "60", + ...> bank_code: "05428", + ...> branch_code: "11101", + ...> national_check: "X", + ...> account_number: "000000123456" + ...> } + ...> |> IbanEx.Country.IT.to_string() + "IT 60 X 05428 11101 000000123456" + ``` """ @size 27 diff --git a/lib/iban_ex/country/jo.ex b/lib/iban_ex/country/jo.ex new file mode 100644 index 0000000..8e397ae --- /dev/null +++ b/lib/iban_ex/country/jo.ex @@ -0,0 +1,42 @@ +defmodule IbanEx.Country.JO do + @moduledoc """ + Jordan IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "JO", + ...> check_digits: "94", + ...> bank_code: "CBJO", + ...> branch_code: "0010", + ...> national_check: nil, + ...> account_number: "000000000131000302" + ...> } + ...> |> IbanEx.Country.JO.to_string() + "JO 94 CBJO 0010 000000000131000302" + ``` + """ + + @size 30 + @rule ~r/^(?[A-Z0-9]{4})(?[0-9]{4})(?[A-Z0-9]{18})$/i + + use IbanEx.Country.Template + + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: _national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/kw.ex b/lib/iban_ex/country/kw.ex new file mode 100644 index 0000000..d788ba3 --- /dev/null +++ b/lib/iban_ex/country/kw.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.KW do + @moduledoc """ + Kuwait IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "KW", + ...> check_digits: "81", + ...> bank_code: "CBKU", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000000000001234560101" + ...> } + ...> |> IbanEx.Country.KW.to_string() + "KW 81 CBKU 0000000000001234560101" + ``` + """ + + @size 30 + @rule ~r/^(?[A-Z0-9]{4})(?[0-9]{22})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/kz.ex b/lib/iban_ex/country/kz.ex new file mode 100644 index 0000000..f5dd645 --- /dev/null +++ b/lib/iban_ex/country/kz.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.KZ do + @moduledoc """ + Kazakhstan IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "KZ", + ...> check_digits: "86", + ...> bank_code: "125", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "KZT5004100100" + ...> } + ...> |> IbanEx.Country.KZ.to_string() + "KZ 86 125 KZT5004100100" + ``` + """ + + @size 20 + @rule ~r/^(?[0-9]{3})(?[A-Z0-9]{13})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/lb.ex b/lib/iban_ex/country/lb.ex new file mode 100644 index 0000000..7b738b1 --- /dev/null +++ b/lib/iban_ex/country/lb.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.LB do + @moduledoc """ + Lebanon IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "LB", + ...> check_digits: "62", + ...> bank_code: "0999", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00000001001901229114" + ...> } + ...> |> IbanEx.Country.LB.to_string() + "LB 62 0999 00000001001901229114" + ``` + """ + + @size 28 + @rule ~r/^(?[0-9]{4})(?[0-9]{20})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/li.ex b/lib/iban_ex/country/li.ex index e8d6f73..ec1537c 100644 --- a/lib/iban_ex/country/li.ex +++ b/lib/iban_ex/country/li.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.LI do ## Examples - iex> %IbanEx.Iban{country_code: "LI", check_digits: "21", bank_code: "08810", branch_code: nil, national_check: nil, account_number: "0002324013AA"} - iex> |> IbanEx.Country.LI.to_string() - "LI 21 08810 0002324013AA" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "LI", + ...> check_digits: "21", + ...> bank_code: "08810", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0002324013AA" + ...> } + ...> |> IbanEx.Country.LI.to_string() + "LI 21 08810 0002324013AA" + ``` """ @size 21 diff --git a/lib/iban_ex/country/lt.ex b/lib/iban_ex/country/lt.ex index 6b55434..444cc4b 100644 --- a/lib/iban_ex/country/lt.ex +++ b/lib/iban_ex/country/lt.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.LT do ## Examples - iex> %IbanEx.Iban{country_code: "LT", check_digits: "12", bank_code: "10000", branch_code: nil, national_check: nil, account_number: "11101001000"} - iex> |> IbanEx.Country.LT.to_string() - "LT 12 10000 11101001000" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "LT", + ...> check_digits: "12", + ...> bank_code: "10000", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "11101001000" + ...> } + ...> |> IbanEx.Country.LT.to_string() + "LT 12 10000 11101001000" + ``` """ @size 20 diff --git a/lib/iban_ex/country/lu.ex b/lib/iban_ex/country/lu.ex index 96ba26c..447c68f 100644 --- a/lib/iban_ex/country/lu.ex +++ b/lib/iban_ex/country/lu.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.LU do ## Examples - iex> %IbanEx.Iban{country_code: "LU", check_digits: "28", bank_code: "001", branch_code: nil, national_check: nil, account_number: "9400644750000"} - iex> |> IbanEx.Country.LU.to_string() - "LU 28 001 9400644750000" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "LU", + ...> check_digits: "28", + ...> bank_code: "001", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "9400644750000" + ...> } + ...> |> IbanEx.Country.LU.to_string() + "LU 28 001 9400644750000" + ``` """ @size 20 diff --git a/lib/iban_ex/country/lv.ex b/lib/iban_ex/country/lv.ex index a57769e..26ac054 100644 --- a/lib/iban_ex/country/lv.ex +++ b/lib/iban_ex/country/lv.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.LV do ## Examples - iex> %IbanEx.Iban{country_code: "LV", check_digits: "80", bank_code: "BANK", branch_code: nil, national_check: nil, account_number: "0000435195001"} - iex> |> IbanEx.Country.LV.to_string() - "LV 80 BANK 0000435195001" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "LV", + ...> check_digits: "80", + ...> bank_code: "BANK", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000435195001" + ...> } + ...> |> IbanEx.Country.LV.to_string() + "LV 80 BANK 0000435195001" + ``` """ @size 21 diff --git a/lib/iban_ex/country/mc.ex b/lib/iban_ex/country/mc.ex index cf541f2..1d23edf 100644 --- a/lib/iban_ex/country/mc.ex +++ b/lib/iban_ex/country/mc.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.MC do ## Examples - iex> %IbanEx.Iban{country_code: "MC", check_digits: "58", bank_code: "11222", branch_code: "00001", national_check: "30", account_number: "01234567890"} - iex> |> IbanEx.Country.MC.to_string() - "MC 58 11222 00001 01234567890 30" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "MC", + ...> check_digits: "58", + ...> bank_code: "11222", + ...> branch_code: "00001", + ...> national_check: "30", + ...> account_number: "01234567890" + ...> } + ...> |> IbanEx.Country.MC.to_string() + "MC 58 11222 00001 01234567890 30" + ``` """ @size 27 diff --git a/lib/iban_ex/country/md.ex b/lib/iban_ex/country/md.ex new file mode 100644 index 0000000..3cdf294 --- /dev/null +++ b/lib/iban_ex/country/md.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.MD do + @moduledoc """ + Republic of Moldova IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "MD", + ...> check_digits: "24", + ...> bank_code: "AG", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "000225100013104168" + ...> } + ...> |> IbanEx.Country.MD.to_string() + "MD 24 AG 000225100013104168" + ``` + """ + + @size 24 + @rule ~r/^(?[A-Z]{2})(?[0-9]{18})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/me.ex b/lib/iban_ex/country/me.ex new file mode 100644 index 0000000..e28e32a --- /dev/null +++ b/lib/iban_ex/country/me.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.ME do + @moduledoc """ + Montenegro IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "ME", + ...> check_digits: "25", + ...> bank_code: "505", + ...> branch_code: nil, + ...> national_check: "51", + ...> account_number: "0000123456789" + ...> } + ...> |> IbanEx.Country.ME.to_string() + "ME 25 505 0000123456789 51" + ``` + """ + + @size 22 + @rule ~r/^(?[0-9]{3})(?[0-9]{13})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/mk.ex b/lib/iban_ex/country/mk.ex new file mode 100644 index 0000000..0593ca7 --- /dev/null +++ b/lib/iban_ex/country/mk.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.MK do + @moduledoc """ + Macedonia IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "MK", + ...> check_digits: "07", + ...> bank_code: "250", + ...> branch_code: nil, + ...> national_check: "84", + ...> account_number: "1200000589" + ...> } + ...> |> IbanEx.Country.MK.to_string() + "MK 07 250 1200000589 84" + ``` + """ + + @size 19 + @rule ~r/^(?[0-9]{3})(?[0-9]{10})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/mr.ex b/lib/iban_ex/country/mr.ex new file mode 100644 index 0000000..3643476 --- /dev/null +++ b/lib/iban_ex/country/mr.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.MR do + @moduledoc """ + Mauritania IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "MR", + ...> check_digits: "13", + ...> bank_code: "00020", + ...> branch_code: "00101", + ...> national_check: "53", + ...> account_number: "00001234567" + ...> } + ...> |> IbanEx.Country.MR.to_string() + "MR 13 00020 00101 00001234567 53" + ``` + """ + + @size 27 + @rule ~r/^(?[0-9]{5})(?[0-9]{5})(?[0-9]{11})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/mt.ex b/lib/iban_ex/country/mt.ex index 477432a..6af90d7 100644 --- a/lib/iban_ex/country/mt.ex +++ b/lib/iban_ex/country/mt.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.MT do ## Examples - iex> %IbanEx.Iban{country_code: "MT", check_digits: "84", bank_code: "MALT", branch_code: "01100", national_check: nil, account_number: "0012345MTLCAST001S"} - iex> |> IbanEx.Country.MT.to_string() - "MT 84 MALT 01100 0012345MTLCAST001S" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "MT", + ...> check_digits: "84", + ...> bank_code: "MALT", + ...> branch_code: "01100", + ...> national_check: nil, + ...> account_number: "0012345MTLCAST001S" + ...> } + ...> |> IbanEx.Country.MT.to_string() + "MT 84 MALT 01100 0012345MTLCAST001S" + ``` """ @size 31 diff --git a/lib/iban_ex/country/nl.ex b/lib/iban_ex/country/nl.ex index 8875c12..fedd396 100644 --- a/lib/iban_ex/country/nl.ex +++ b/lib/iban_ex/country/nl.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.NL do ## Examples - iex> %IbanEx.Iban{country_code: "NL", check_digits: "91", bank_code: "ABNA", branch_code: nil, national_check: nil, account_number: "0417164300"} - iex> |> IbanEx.Country.NL.to_string() - "NL 91 ABNA 0417164300" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "NL", + ...> check_digits: "91", + ...> bank_code: "ABNA", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0417164300" + ...> } + ...> |> IbanEx.Country.NL.to_string() + "NL 91 ABNA 0417164300" + ``` """ @size 18 diff --git a/lib/iban_ex/country/no.ex b/lib/iban_ex/country/no.ex index b30dd8d..9c3e498 100644 --- a/lib/iban_ex/country/no.ex +++ b/lib/iban_ex/country/no.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.NO do ## Examples - iex> %IbanEx.Iban{country_code: "NO", check_digits: "93", bank_code: "8601", branch_code: nil, national_check: "7", account_number: "111794"} - iex> |> IbanEx.Country.NO.to_string() - "NO 93 8601 111794 7" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "NO", + ...> check_digits: "93", + ...> bank_code: "8601", + ...> branch_code: nil, + ...> national_check: "7", + ...> account_number: "111794" + ...> } + ...> |> IbanEx.Country.NO.to_string() + "NO 93 8601 111794 7" + ``` """ @size 15 diff --git a/lib/iban_ex/country/pk.ex b/lib/iban_ex/country/pk.ex new file mode 100644 index 0000000..178aeed --- /dev/null +++ b/lib/iban_ex/country/pk.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.PK do + @moduledoc """ + Pakistan IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "PK", + ...> check_digits: "36", + ...> bank_code: "SCBL", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000001123456702" + ...> } + ...> |> IbanEx.Country.PK.to_string() + "PK 36 SCBL 0000001123456702" + ``` + """ + + @size 24 + @rule ~r/^(?[A-Z]{4})(?[0-9]{16})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/pl.ex b/lib/iban_ex/country/pl.ex index 3a94d09..23f1ec6 100644 --- a/lib/iban_ex/country/pl.ex +++ b/lib/iban_ex/country/pl.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.PL do ## Examples - iex> %IbanEx.Iban{country_code: "PL", check_digits: "61", bank_code: "109", branch_code: "0101", national_check: "4", account_number: "0000071219812874"} - iex> |> IbanEx.Country.PL.to_string() - "PL 61 109 0101 4 0000071219812874" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "PL", + ...> check_digits: "61", + ...> bank_code: "109", + ...> branch_code: "0101", + ...> national_check: "4", + ...> account_number: "0000071219812874" + ...> } + ...> |> IbanEx.Country.PL.to_string() + "PL 61 109 0101 4 0000071219812874" + ``` """ @size 28 diff --git a/lib/iban_ex/country/pt.ex b/lib/iban_ex/country/pt.ex index d485910..9692382 100644 --- a/lib/iban_ex/country/pt.ex +++ b/lib/iban_ex/country/pt.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.PT do ## Examples - iex> %IbanEx.Iban{country_code: "PT", check_digits: "50", bank_code: "0002", branch_code: "0123", national_check: "54", account_number: "12345678901"} - iex> |> IbanEx.Country.PT.to_string() - "PT 50 0002 0123 12345678901 54" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "PT", + ...> check_digits: "50", + ...> bank_code: "0002", + ...> branch_code: "0123", + ...> national_check: "54", + ...> account_number: "12345678901" + ...> } + ...> |> IbanEx.Country.PT.to_string() + "PT 50 0002 0123 12345678901 54" + ``` """ @size 25 diff --git a/lib/iban_ex/country/qa.ex b/lib/iban_ex/country/qa.ex new file mode 100644 index 0000000..e2557d4 --- /dev/null +++ b/lib/iban_ex/country/qa.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.QA do + @moduledoc """ + Qatar IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "QA", + ...> check_digits: "58", + ...> bank_code: "DOHB", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00001234567890ABCDEFG" + ...> } + ...> |> IbanEx.Country.QA.to_string() + "QA 58 DOHB 00001234567890ABCDEFG" + ``` + """ + + @size 29 + @rule ~r/^(?[A-Z]{4})(?[A-Z0-9]{21})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/ro.ex b/lib/iban_ex/country/ro.ex index 8e34b4e..5d6d989 100644 --- a/lib/iban_ex/country/ro.ex +++ b/lib/iban_ex/country/ro.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.RO do ## Examples - iex> %IbanEx.Iban{country_code: "RO", check_digits: "49", bank_code: "AAAA", branch_code: nil, national_check: nil, account_number: "1B31007593840000"} - iex> |> IbanEx.Country.RO.to_string() - "RO 49 AAAA 1B31007593840000" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "RO", + ...> check_digits: "49", + ...> bank_code: "AAAA", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "1B31007593840000" + ...> } + ...> |> IbanEx.Country.RO.to_string() + "RO 49 AAAA 1B31007593840000" + ``` """ @size 24 diff --git a/lib/iban_ex/country/rs.ex b/lib/iban_ex/country/rs.ex new file mode 100644 index 0000000..f4ab410 --- /dev/null +++ b/lib/iban_ex/country/rs.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.RS do + @moduledoc """ + Serbia IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "RS", + ...> check_digits: "35", + ...> bank_code: "260", + ...> branch_code: nil, + ...> national_check: "79", + ...> account_number: "0056010016113" + ...> } + ...> |> IbanEx.Country.RS.to_string() + "RS 35 260 0056010016113 79" + ``` + """ + + @size 22 + @rule ~r/^(?[0-9]{3})(?[0-9]{13})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/sa.ex b/lib/iban_ex/country/sa.ex new file mode 100644 index 0000000..ff67ca9 --- /dev/null +++ b/lib/iban_ex/country/sa.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.SA do + @moduledoc """ + Saudi Arabia IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SA", + ...> check_digits: "03", + ...> bank_code: "80", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "000000608010167519" + ...> } + ...> |> IbanEx.Country.SA.to_string() + "SA 03 80 000000608010167519" + ``` + """ + + @size 24 + @rule ~r/^(?[0-9]{2})(?[0-9]{18})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/se.ex b/lib/iban_ex/country/se.ex index 3eaa3ac..3457551 100644 --- a/lib/iban_ex/country/se.ex +++ b/lib/iban_ex/country/se.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.SE do ## Examples - iex> %IbanEx.Iban{country_code: "SE", check_digits: "45", bank_code: "500", branch_code: nil, national_check: nil, account_number: "00000058398257466"} - iex> |> IbanEx.Country.SE.to_string() - "SE 45 500 00000058398257466" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SE", + ...> check_digits: "45", + ...> bank_code: "500", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00000058398257466" + ...> } + ...> |> IbanEx.Country.SE.to_string() + "SE 45 500 00000058398257466" + ``` """ @size 24 diff --git a/lib/iban_ex/country/si.ex b/lib/iban_ex/country/si.ex index 74bea8a..1f34a78 100644 --- a/lib/iban_ex/country/si.ex +++ b/lib/iban_ex/country/si.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.SI do ## Examples - iex> %IbanEx.Iban{country_code: "SI", check_digits: "56", bank_code: "26", branch_code: "330", national_check: "86", account_number: "00120390"} - iex> |> IbanEx.Country.SI.to_string() - "SI 56 26 330 00120390 86" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SI", + ...> check_digits: "56", + ...> bank_code: "26", + ...> branch_code: "330", + ...> national_check: "86", + ...> account_number: "00120390" + ...> } + ...> |> IbanEx.Country.SI.to_string() + "SI 56 26 330 00120390 86" + ``` """ @size 19 diff --git a/lib/iban_ex/country/sk.ex b/lib/iban_ex/country/sk.ex index 5db8f03..d102e0b 100644 --- a/lib/iban_ex/country/sk.ex +++ b/lib/iban_ex/country/sk.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.SK do ## Examples - iex> %IbanEx.Iban{country_code: "SK", check_digits: "31", bank_code: "1200", branch_code: nil, national_check: nil, account_number: "0000198742637541"} - iex> |> IbanEx.Country.SK.to_string() - "SK 31 1200 0000198742637541" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SK", + ...> check_digits: "31", + ...> bank_code: "1200", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000198742637541" + ...> } + ...> |> IbanEx.Country.SK.to_string() + "SK 31 1200 0000198742637541" + ``` """ @size 24 diff --git a/lib/iban_ex/country/sm.ex b/lib/iban_ex/country/sm.ex index 41103c0..d8f6d87 100644 --- a/lib/iban_ex/country/sm.ex +++ b/lib/iban_ex/country/sm.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.SM do ## Examples - iex> %IbanEx.Iban{country_code: "SM", check_digits: "86", bank_code: "03225", branch_code: "09800", national_check: "U", account_number: "000000270100"} - iex> |> IbanEx.Country.SM.to_string() - "SM 86 U 03225 09800 000000270100" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SM", + ...> check_digits: "86", + ...> bank_code: "03225", + ...> branch_code: "09800", + ...> national_check: "U", + ...> account_number: "000000270100" + ...> } + ...> |> IbanEx.Country.SM.to_string() + "SM 86 U 03225 09800 000000270100" + ``` """ @size 27 diff --git a/lib/iban_ex/country/sv.ex b/lib/iban_ex/country/sv.ex new file mode 100644 index 0000000..126db49 --- /dev/null +++ b/lib/iban_ex/country/sv.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.SV do + @moduledoc """ + El Salvador IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "SV", + ...> check_digits: "62", + ...> bank_code: "CENR", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "00000000000000700025" + ...> } + ...> |> IbanEx.Country.SV.to_string() + "SV 62 CENR 00000000000000700025" + ``` + """ + + @size 28 + @rule ~r/^(?[A-Z0-9]{4})(?[0-9]{20})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/template.ex b/lib/iban_ex/country/template.ex index a20f182..8d413bc 100644 --- a/lib/iban_ex/country/template.ex +++ b/lib/iban_ex/country/template.ex @@ -36,7 +36,7 @@ defmodule IbanEx.Country.Template do end @impl IbanEx.Country.Template - @spec size() :: Integer.t() + @spec size() :: integer() def size(), do: @size @impl IbanEx.Country.Template diff --git a/lib/iban_ex/country/tl.ex b/lib/iban_ex/country/tl.ex new file mode 100644 index 0000000..72b4389 --- /dev/null +++ b/lib/iban_ex/country/tl.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.TL do + @moduledoc """ + Timor-Leste IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "TL", + ...> check_digits: "38", + ...> bank_code: "008", + ...> branch_code: nil, + ...> national_check: "57", + ...> account_number: "00123456789101" + ...> } + ...> |> IbanEx.Country.TL.to_string() + "TL 38 008 00123456789101 57" + ``` + """ + + @size 23 + @rule ~r/^(?[0-9]{3})(?[0-9]{14})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/tr.ex b/lib/iban_ex/country/tr.ex new file mode 100644 index 0000000..0dbaba7 --- /dev/null +++ b/lib/iban_ex/country/tr.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.TR do + @moduledoc """ + Turkey IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "TR", + ...> check_digits: "33", + ...> bank_code: "00061", + ...> branch_code: nil, + ...> national_check: "0", + ...> account_number: "0519786457841326" + ...> } + ...> |> IbanEx.Country.TR.to_string() + "TR 33 00061 0 0519786457841326" + ``` + """ + + @size 26 + @rule ~r/^(?[A-Z0-9]{5})(?[0-9]{1})(?[0-9]{16})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: _branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, national_check, account_number] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/country/ua.ex b/lib/iban_ex/country/ua.ex index c763292..62fbcd2 100644 --- a/lib/iban_ex/country/ua.ex +++ b/lib/iban_ex/country/ua.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.UA do ## Examples - iex> %IbanEx.Iban{country_code: "UA", check_digits: "21", bank_code: "322313", branch_code: nil, national_check: nil, account_number: "0000026007233566001"} - iex> |> IbanEx.Country.UA.to_string() - "UA 21 322313 0000026007233566001" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "UA", + ...> check_digits: "21", + ...> bank_code: "322313", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000026007233566001" + ...> } + ...> |> IbanEx.Country.UA.to_string() + "UA 21 322313 0000026007233566001" + ``` """ @size 29 diff --git a/lib/iban_ex/country/va.ex b/lib/iban_ex/country/va.ex index 70d7ec8..c8b1d3a 100644 --- a/lib/iban_ex/country/va.ex +++ b/lib/iban_ex/country/va.ex @@ -4,10 +4,18 @@ defmodule IbanEx.Country.VA do ## Examples - iex> %IbanEx.Iban{country_code: "VA", check_digits: "59", bank_code: "001", branch_code: nil, national_check: nil, account_number: "123000012345678"} - iex> |> IbanEx.Country.VA.to_string() - "VA 59 001 123000012345678" - + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "VA", + ...> check_digits: "59", + ...> bank_code: "001", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "123000012345678" + ...> } + ...> |> IbanEx.Country.VA.to_string() + "VA 59 001 123000012345678" + ``` """ @size 22 diff --git a/lib/iban_ex/country/vg.ex b/lib/iban_ex/country/vg.ex new file mode 100644 index 0000000..95334e2 --- /dev/null +++ b/lib/iban_ex/country/vg.ex @@ -0,0 +1,25 @@ +defmodule IbanEx.Country.VG do + @moduledoc """ + British Virgin Islands IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "VG", + ...> check_digits: "96", + ...> bank_code: "VPVG", + ...> branch_code: nil, + ...> national_check: nil, + ...> account_number: "0000012345678901" + ...> } + ...> |> IbanEx.Country.VG.to_string() + "VG 96 VPVG 0000012345678901" + ``` + """ + + @size 24 + @rule ~r/^(?[A-Z]{4})(?[0-9]{16})$/i + + use IbanEx.Country.Template +end diff --git a/lib/iban_ex/country/xk.ex b/lib/iban_ex/country/xk.ex new file mode 100644 index 0000000..f15e675 --- /dev/null +++ b/lib/iban_ex/country/xk.ex @@ -0,0 +1,43 @@ +defmodule IbanEx.Country.XK do + @moduledoc """ + Kosovo IBAN parsing rules + + ## Examples + + ```elixir + iex> %IbanEx.Iban{ + ...> country_code: "XK", + ...> check_digits: "05", + ...> bank_code: "12", + ...> branch_code: "12", + ...> national_check: "06", + ...> account_number: "0123456789" + ...> } + ...> |> IbanEx.Country.XK.to_string() + "XK 05 12 12 0123456789 06" + ``` + """ + + @size 20 + @rule ~r/^(?[0-9]{2})(?[0-9]{2})(?[0-9]{10})(?[0-9]{2})$/i + + use IbanEx.Country.Template + + @impl IbanEx.Country.Template + @spec to_string(Iban.t()) :: binary() + @spec to_string(Iban.t(), binary()) :: binary() + def to_string( + %Iban{ + country_code: country_code, + check_digits: check_digits, + bank_code: bank_code, + branch_code: branch_code, + national_check: national_check, + account_number: account_number + } = _iban, + joiner \\ " " + ) do + [country_code, check_digits, bank_code, branch_code, account_number, national_check] + |> Enum.join(joiner) + end +end diff --git a/lib/iban_ex/deserialize.ex b/lib/iban_ex/deserialize.ex index 9079917..cd3e656 100644 --- a/lib/iban_ex/deserialize.ex +++ b/lib/iban_ex/deserialize.ex @@ -1,14 +1,27 @@ defprotocol IbanEx.Deserialize do - @type iban_or_error() :: IbanEx.Iban.t() | {:error, :can_not_parse_map | atom()} + @type iban() :: IbanEx.Iban.t() + @type iban_or_error() :: + iban() + | {:invalid_checksum, binary()} + | {:invalid_format, binary()} + | {:invalid_length, binary()} + | {:can_not_parse_map, binary()} + | {:unsupported_country_code, binary()} + @spec to_iban(t()) :: iban_or_error() def to_iban(value) end defimpl IbanEx.Deserialize, for: [BitString, String] do alias IbanEx.{Parser, Error} - @type iban_or_error() :: IbanEx.Iban.t() | {:error, atom()} - @spec to_iban(binary()) :: iban_or_error() - @spec to_iban(String.t()) :: iban_or_error() + @type iban() :: IbanEx.Iban.t() + @type iban_or_error() :: + iban() + | {:invalid_checksum, binary()} + | {:invalid_format, binary()} + | {:invalid_length, binary()} + | {:can_not_parse_map, binary()} + | {:unsupported_country_code, binary()} def to_iban(string) do case Parser.parse(string) do {:ok, iban} -> iban @@ -18,10 +31,17 @@ defimpl IbanEx.Deserialize, for: [BitString, String] do end defimpl IbanEx.Deserialize, for: Map do - alias IbanEx.Iban - @type iban_or_error() :: IbanEx.Iban.t() | {:error, :can_not_parse_map} + alias IbanEx.{Iban, Error} + + @type iban() :: IbanEx.Iban.t() + @type iban_or_error() :: + iban() + | {:invalid_checksum, binary()} + | {:invalid_format, binary()} + | {:invalid_length, binary()} + | {:can_not_parse_map, binary()} + | {:unsupported_country_code, binary()} - @spec to_iban(map()) :: iban_or_error() def to_iban( %{ country_code: _country_code, @@ -49,13 +69,10 @@ defimpl IbanEx.Deserialize, for: Map do to_iban(atomized_map) end - def to_iban(map) when is_map(map), do: {:error, :can_not_parse_map} + def to_iban(map) when is_map(map), do: {:can_not_parse_map, Error.message(:can_not_parse_map)} end defimpl IbanEx.Deserialize, for: List do alias IbanEx.Iban - @type iban_or_error() :: IbanEx.Iban.t() | {:error, :can_not_parse_map} - - @spec to_iban(list()) :: iban_or_error() def to_iban(list), do: struct(Iban, Map.new(list)) end diff --git a/lib/iban_ex/parser.ex b/lib/iban_ex/parser.ex index 0f365ad..badfa88 100644 --- a/lib/iban_ex/parser.ex +++ b/lib/iban_ex/parser.ex @@ -7,11 +7,20 @@ defmodule IbanEx.Parser do @type iban_string() :: String.t() @type country_code_string() :: <<_::16>> @type check_digits_string() :: <<_::16>> - @type iban_or_error() :: IbanEx.Iban.t() | {:error, atom()} - @spec parse({:ok, String.t()} | String.t()) :: iban_or_error() + @type iban() :: IbanEx.Iban.t() + @type iban_or_error() :: + {:ok, iban()} + | {:invalid_checksum, binary()} + | {:invalid_format, binary()} + | {:invalid_length, binary()} + | {:can_not_parse_map, binary()} + | {:unsupported_country_code, binary()} + + @spec parse({:ok, binary()}) :: iban_or_error() def parse({:ok, iban_string}), do: parse(iban_string) + @spec parse(binary()) :: iban_or_error() def parse(iban_string) do case Validator.validate(iban_string) do {:ok, valid_iban} -> diff --git a/lib/iban_ex/serialize.ex b/lib/iban_ex/serialize.ex index c7445fb..936e0e2 100644 --- a/lib/iban_ex/serialize.ex +++ b/lib/iban_ex/serialize.ex @@ -6,6 +6,6 @@ defmodule IbanEx.Serialize do @spec to_string(Iban.t()) :: String.t() def to_string(iban), do: Formatter.format(iban) - @spec to_map(Iban.t()) :: Map.t() + @spec to_map(Iban.t()) :: map() def to_map(iban), do: Map.from_struct(iban) end diff --git a/lib/iban_ex/validator/validator.ex b/lib/iban_ex/validator/validator.ex index 3782a67..b9f916b 100644 --- a/lib/iban_ex/validator/validator.ex +++ b/lib/iban_ex/validator/validator.ex @@ -14,7 +14,7 @@ defmodule IbanEx.Validator do {&__MODULE__.iban_violates_format?/1, {:error, :invalid_format}}, {&__MODULE__.iban_unsupported_country?/1, {:error, :unsupported_country_code}}, {&__MODULE__.iban_violates_length?/1, {:error, :invalid_length}}, - {&__MODULE__.iban_violates_country_rule?/1, {:error, :invalid_format}}, + {&__MODULE__.iban_violates_country_rule?/1, {:error, :invalid_format_for_country}}, {&__MODULE__.iban_violates_checksum?/1, {:error, :invalid_checksum}} ] @@ -39,13 +39,21 @@ defmodule IbanEx.Validator do iban_violates_checksum? """ - @spec validate(String.t()) :: {:ok, String.t()} | {:error, Atom.t()} + @type iban() :: binary() + @type iban_or_error() :: + {:ok, iban()} + | {:invalid_checksum, binary()} + | {:invalid_format, binary()} + | {:invalid_length, binary()} + | {:unsupported_country_code, binary()} + @spec validate(String.t()) :: {:ok, String.t()} | {:error, atom()} + def validate(iban) do cond do iban_violates_format?(iban) -> {:error, :invalid_format} iban_unsupported_country?(iban) -> {:error, :unsupported_country_code} iban_violates_length?(iban) -> {:error, :invalid_length} - iban_violates_country_rule?(iban) -> {:error, :invalid_format} + iban_violates_country_rule?(iban) -> {:error, :invalid_format_for_country} iban_violates_checksum?(iban) -> {:error, :invalid_checksum} true -> {:ok, normalize(iban)} end @@ -86,21 +94,23 @@ defmodule IbanEx.Validator do end @doc "Check length of IBAN" - @spec check_iban_length(String.t()) :: {:error, :length_to_short | :length_to_long } | :ok + @spec check_iban_length(String.t()) :: {:error, :length_to_short | :length_to_long} | :ok def check_iban_length(iban) do - unless iban_unsupported_country?(iban) do - country_module = - iban - |> Parser.country_code() - |> Country.country_module() + case iban_unsupported_country?(iban) do + true -> + {:error, :unsupported_country_code} - case country_module.size() - size(iban) do - diff when diff > 0 -> {:error, :length_to_short} - diff when diff < 0 -> {:error, :length_to_long} - 0 -> :ok - end - else - {:error, :unsupported_country_code} + false -> + country_module = + iban + |> Parser.country_code() + |> Country.country_module() + + case country_module.size() - size(iban) do + diff when diff > 0 -> {:error, :length_to_short} + diff when diff < 0 -> {:error, :length_to_long} + 0 -> :ok + end end end diff --git a/mix.exs b/mix.exs index 2a36cd4..976567b 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule IbanEx.MixProject do use Mix.Project @source_url "https://g.tulz.dev/opensource/iban-ex" - @version "0.1.5" + @version "0.1.6" def project do [ diff --git a/test/iban_ex_test.exs b/test/iban_ex_test.exs index dde8525..00d57e0 100644 --- a/test/iban_ex_test.exs +++ b/test/iban_ex_test.exs @@ -2,42 +2,74 @@ defmodule IbanExTest do alias IbanEx.{Country, Iban, Parser} use ExUnit.Case, async: true doctest_file "README.md" + doctest IbanEx.Country.AD + doctest IbanEx.Country.AE + doctest IbanEx.Country.AL doctest IbanEx.Country.AT + doctest IbanEx.Country.AZ + doctest IbanEx.Country.BA doctest IbanEx.Country.BE doctest IbanEx.Country.BG + doctest IbanEx.Country.BH + doctest IbanEx.Country.BR doctest IbanEx.Country.CH + doctest IbanEx.Country.CR doctest IbanEx.Country.CY doctest IbanEx.Country.CZ doctest IbanEx.Country.DE doctest IbanEx.Country.DK + doctest IbanEx.Country.DO doctest IbanEx.Country.EE + doctest IbanEx.Country.EG doctest IbanEx.Country.ES doctest IbanEx.Country.FI + doctest IbanEx.Country.FO doctest IbanEx.Country.FR doctest IbanEx.Country.GB + doctest IbanEx.Country.GE doctest IbanEx.Country.GI + doctest IbanEx.Country.GL doctest IbanEx.Country.GR + doctest IbanEx.Country.GT + doctest IbanEx.Country.JO doctest IbanEx.Country.HR doctest IbanEx.Country.HU doctest IbanEx.Country.IE + doctest IbanEx.Country.IL doctest IbanEx.Country.IT + doctest IbanEx.Country.KZ + doctest IbanEx.Country.KW + doctest IbanEx.Country.LB doctest IbanEx.Country.LI doctest IbanEx.Country.LT doctest IbanEx.Country.LU doctest IbanEx.Country.LV doctest IbanEx.Country.MC + doctest IbanEx.Country.MD + doctest IbanEx.Country.ME + doctest IbanEx.Country.MK + doctest IbanEx.Country.MR doctest IbanEx.Country.MT doctest IbanEx.Country.NL doctest IbanEx.Country.NO + doctest IbanEx.Country.PK doctest IbanEx.Country.PL doctest IbanEx.Country.PT + doctest IbanEx.Country.QA doctest IbanEx.Country.RO + doctest IbanEx.Country.RS + doctest IbanEx.Country.SA doctest IbanEx.Country.SE - doctest IbanEx.Country.SM doctest IbanEx.Country.SI doctest IbanEx.Country.SK + doctest IbanEx.Country.SM + doctest IbanEx.Country.SV + doctest IbanEx.Country.TL + doctest IbanEx.Country.TR doctest IbanEx.Country.UA doctest IbanEx.Country.VA + doctest IbanEx.Country.VG + doctest IbanEx.Country.XK @ibans [ "AL47212110090000000235698741",