Current section
Files
Jump to
Current section
Files
lib/ccxt/extract/emulated_methods.ex
defmodule CCXT.Extract.EmulatedMethods do
@moduledoc """
Loads emulated method sources extracted from CCXT TypeScript files.
Data source: `priv/extractor/ccxt_emulated_methods.json`.
"""
# Inline priv path resolution to avoid compile-time dependency on CCXT.Priv
# (which would cause cascading recompilation of ~200 exchange modules)
@json_path (case :code.priv_dir(:ccxt_client) do
{:error, :bad_name} ->
[__DIR__, "..", "..", "priv", "extractor/ccxt_emulated_methods.json"] |> Path.join() |> Path.expand()
priv when is_list(priv) ->
Path.join(List.to_string(priv), "extractor/ccxt_emulated_methods.json")
end)
@doc "Returns the JSON file path for emulated method extraction."
@spec path() :: String.t()
def path, do: @json_path
@doc """
Loads the emulated methods JSON with caching.
Call `reload!/0` to force re-read.
"""
@spec load() :: map()
def load do
case :persistent_term.get({__MODULE__, :data}, :missing) do
:missing ->
data = read_json!()
:persistent_term.put({__MODULE__, :data}, data)
data
data ->
data
end
end
@doc "Reloads the emulated methods JSON (bypassing cache)."
@spec reload!() :: map()
def reload! do
data = read_json!()
:persistent_term.put({__MODULE__, :data}, data)
data
end
@doc "Returns all exchange IDs with emulated methods."
@spec exchanges() :: [String.t()]
def exchanges do
load()
|> Map.get("emulated_methods", %{})
|> Map.keys()
|> Enum.sort()
end
@doc "Returns all emulated method entries for an exchange."
@spec methods_for(String.t()) :: [map()]
def methods_for(exchange_id) do
load()
|> Map.get("emulated_methods", %{})
|> Map.get(exchange_id, [])
end
@doc "Returns emulated method names for an exchange."
@spec method_names_for(String.t()) :: [String.t()]
def method_names_for(exchange_id) do
exchange_id
|> methods_for()
|> Enum.map(&Map.get(&1, "name"))
end
@doc "Returns an emulated method entry by name for an exchange."
@spec method_for(String.t(), String.t()) :: map() | nil
def method_for(exchange_id, method_name) do
exchange_id
|> methods_for()
|> Enum.find(fn method -> Map.get(method, "name") == method_name end)
end
@doc ~s{Returns emulated method entries filtered by scope ("rest" or "ws").}
@spec methods_for_scope(String.t(), String.t()) :: [map()]
def methods_for_scope(exchange_id, scope) when is_binary(scope) do
exchange_id
|> methods_for()
|> Enum.filter(fn method -> Map.get(method, "scope") == scope end)
end
@doc false
# Reads and parses the emulated methods JSON file from disk
defp read_json! do
@json_path
|> File.read!()
|> Jason.decode!()
end
end