Packages
ex_cldr_calendars
2.4.4
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.1
2.3.0
2.2.0
2.1.1
2.1.0
2.0.0
1.26.4
1.26.3
1.26.2
1.26.1
1.26.0
1.25.2
1.25.1
1.25.0
1.24.2
1.24.1
1.24.0
retired
1.23.1
1.23.0
1.22.1
1.22.0
1.21.0
1.20.0
1.19.0
1.18.1
1.18.0
1.17.3
1.17.2
1.17.1
1.17.0
1.17.0-rc.3
1.17.0-rc.2
1.17.0-rc.1
1.17.0-rc.0
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.1
1.14.0
1.13.0
1.13.0-rc.1
1.13.0-rc.0
1.12.1
1.12.0
1.11.0
1.11.0-rc.0
1.10.1
1.10.0
1.9.0
1.8.1
1.8.0
1.8.0-rc.0
1.7.1
1.7.0
1.6.0
1.5.1
1.5.0
retired
1.4.0
retired
1.3.0
retired
1.2.0
retired
1.1.0
retired
1.0.0
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.1
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.0
retired
Localized month- and week-based calendars and calendar functions based upon CLDR data.
Current section
Files
Jump to
Current section
Files
lib/cldr/calendar/compiler.ex
defmodule Cldr.Calendar.Compiler do
@moduledoc false
use GenServer
require Logger
alias Cldr.Calendar.Config
@default_compiler_timeout 7_000
def start_link(state) do
GenServer.start_link(__MODULE__, state, name: __MODULE__)
end
def create_calendar(calendar_module, calendar_type, config) do
# Fast path: if the calendar module is already loaded there is nothing
# to compile. Short-circuit before touching the GenServer so concurrent
# callers don't serialise behind whichever compile happens to be in
# flight. The GenServer's own Code.ensure_loaded?/1 check in
# handle_call/3 still guards against a race when two callers request
# the same not-yet-loaded module at the same time.
if Code.ensure_loaded?(calendar_module) do
{:ok, calendar_module}
else
do_create_calendar(calendar_module, calendar_type, config)
end
end
defp do_create_calendar(calendar_module, calendar_type, config) do
config = Keyword.put(config, :calendar, calendar_module)
structured_config = Config.extract_options(config)
with {:ok, config} <- Config.validate_config(structured_config, calendar_type) do
calendar_type =
calendar_type
|> to_string
|> String.capitalize()
config =
config
|> Map.from_struct()
|> Map.to_list()
contents =
quote do
use unquote(Module.concat(Cldr.Calendar.Base, calendar_type)),
unquote(Macro.escape(config))
end
gen_server_timeout =
Application.get_env(:ex_cldr_calendars, :compiler_timeout, @default_compiler_timeout)
Logger.debug("Requesting compilation of calendar module #{inspect(calendar_module)}")
GenServer.call(
__MODULE__,
{
:compile,
calendar_module,
contents,
Macro.Env.location(__ENV__)
},
gen_server_timeout
)
end
end
## Callbacks
@impl true
def init(state) do
{:ok, state}
end
@impl true
def handle_call({:compile, module, contents, env}, _from, state) do
cond do
Code.ensure_loaded?(module) ->
Logger.debug("Calendar module #{inspect(module)} already defined, returning it")
{:reply, {:ok, module}, state}
{:module, module, _, :ok} = Module.create(module, contents, env) ->
Logger.debug("Created calendar module #{inspect(module)}")
{:reply, {:ok, module}, state}
end
end
end