Current section

Files

Jump to
igniter_js lib igniter_js helpers.ex
Raw

lib/igniter_js/helpers.ex

defmodule IgniterJs.Helpers do
@moduledoc """
A module that contains helper functions for IgniterJs. For example it helps to normalize the
output of the NIFs, read and validate the file, and call the NIF function with the
given file path or content.
"""
@doc """
Normalize the output of the NIFs. It is a macro and returns a tuple with the first
element as the output, the second element as the caller function name, and the
third element as the status.
```elixir
require IgniterJs.Helpers
normalize_output({:ok, :fun_atom, result}, __ENV__.function)
normalize_output({:error, :fun_atom, result}, __ENV__.function)
```
"""
defmacro normalize_output(output, caller_function) do
quote do
{elem(unquote(output), 0), elem(unquote(caller_function), 0), elem(unquote(output), 2)}
end
end
@doc """
Read and validate the file. It returns the file content if the file exists and the
extension is `.js` or `.ts`, otherwise, it returns an error tuple.
```elixir
read_and_validate_file("/path/to/file.js")
```
"""
# sobelow_skip ["Traversal.FileModule"]
def read_and_validate_file(file_path) do
with true <- File.exists?(file_path),
true <- Path.extname(file_path) in [".js", ".ts"],
{:ok, file_content} <- File.read(file_path) do
{:ok, file_content}
else
{:error, reason} -> {:error, reason}
_ -> {:error, "Invalid file path or format."}
end
end
@doc """
Call the NIF function with the given file path or content and return the result.
It helps to change the function name as atom based on its caller function.
```elixir
call_nif_fn("/path/to/file.js", __ENV__.function, fn content -> content end, :path)
call_nif_fn("file content", __ENV__.function, fn content -> content end)
call_nif_fn("file content", __ENV__.function, fn content -> content end, :content)
```
"""
def call_nif_fn(file_path, caller_function, processing_fn, type \\ :content)
def call_nif_fn(file_content, caller_function, processing_fn, :content) do
processing_fn.(file_content)
|> normalize_output(caller_function)
end
def call_nif_fn(file_path, caller_function, processing_fn, :path) do
case read_and_validate_file(file_path) do
{:ok, file_content} ->
processing_fn.(file_content)
|> normalize_output(caller_function)
reason ->
Tuple.insert_at(reason, 1, :none)
|> normalize_output(caller_function)
end
end
end