defmodule Cnum.Brands do @moduledoc false # Brands is an in-memory table that stores supported credit cards' # Bank Identification Numbers according to their credit card brands. use GenServer @table_name :bins # Client def start_link(_arg) do GenServer.start_link(__MODULE__, nil, name: __MODULE__) end def get(key) do GenServer.call(__MODULE__, {:get, key}) end # Ets methods def init(_) do :ets.new(@table_name, [:named_table]) populate() {:ok, @table_name} end def handle_call({:get, key}, _from, state) do reply = case :ets.lookup(@table_name, key) do [] -> nil [{_key, value}] -> value end {:reply, reply, state} end # -------------------------------------------------- # defp brands() do [ {"amex", ["34", "37"]}, {"diners club", [300..305, "3095", "36", 38..39 ]}, {"discover", ["6011", 622126..622925, 624000..626999, 628200..628899, "64", "65"]}, {"jcb", [3528..3589]}, {"maestro", ["6304", "6759", "6761", "6763", "676770", "676774"]}, {"master card", [2221..2720, 51..55]}, {"visa", ["4"]}, {"visa electron", ["4026", "417500", "4405", "4508", "4844", "4913", "4917"]}, ] end defp populate do for {brand, values} <- brands() do for first_digits <- values, do: seed_data(brand, first_digits) end end defp seed_data(brand, %Range{} = range) do for first_digits <- range do :ets.insert(@table_name, {"#{first_digits}", brand}) end end defp seed_data(brand, first_digits) when is_binary(first_digits) do :ets.insert(@table_name, {first_digits, brand}) end end