Packages
vix
0.20.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.1
0.33.0
0.32.0
0.31.1
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.2.1
0.2.0
retired
0.1.0
NIF based bindings for libvips
Current section
Files
Jump to
Current section
Files
lib/vix/vips/mutable_operation.ex
defmodule Vix.Vips.MutableOperation do
@moduledoc """
Module for Vix.Vips.MutableOperation.
"""
import Vix.Vips.OperationHelper
defmodule Error do
defexception [:message]
end
# define typespec for enums
Enum.map(vips_enum_list(), fn {name, enum} ->
{enum_str_list, _} = Enum.unzip(enum)
@type unquote(type_name(name)) :: unquote(atom_typespec_ast(enum_str_list))
end)
# define typespec for flags
Enum.map(vips_flag_list(), fn {name, flag} ->
{flag_str_list, _} = Enum.unzip(flag)
@type unquote(type_name(name)) :: list(unquote(atom_typespec_ast(flag_str_list)))
end)
Enum.map(vips_mutable_operation_list(), fn name ->
%{
desc: desc,
in_req_spec: in_req_spec,
in_opt_spec: in_opt_spec,
out_req_spec: out_req_spec,
out_opt_spec: out_opt_spec
} = spec = operation_args_spec(name)
# ensure only first param is mutable image
[%{type: "MutableVipsImage"} | remaining_args] = in_req_spec ++ in_opt_spec
if Enum.any?(remaining_args, &(&1.type == "MutableVipsImage")) do
raise "Only first param can be MutableVipsImage"
end
func_name = function_name(name)
req_params =
Enum.map(in_req_spec, fn param ->
param.param_name
|> String.to_atom()
|> Macro.var(__MODULE__)
end)
@doc """
#{prepare_doc(desc, in_req_spec, in_opt_spec, out_req_spec, out_opt_spec)}
"""
@spec unquote(func_typespec(func_name, in_req_spec, in_opt_spec, out_req_spec, out_opt_spec))
if in_opt_spec == [] do
# operations without optional arguments
def unquote(func_name)(unquote_splicing(req_params)) do
[mutable_image | rest_params] = unquote(req_params)
operation_cb = fn image ->
operation_call(
unquote(name),
[image | rest_params],
[],
unquote(Macro.escape(spec))
)
end
GenServer.call(mutable_image.pid, {:operation, operation_cb})
end
else
# operations with optional arguments
def unquote(func_name)(unquote_splicing(req_params), optional \\ []) do
[mutable_image | rest_params] = unquote(req_params)
operation_cb = fn image ->
operation_call(
unquote(name),
[image | rest_params],
optional,
unquote(Macro.escape(spec))
)
end
GenServer.call(mutable_image.pid, {:operation, operation_cb})
end
end
bang_func_name = function_name(String.to_atom(name <> "!"))
@doc """
#{prepare_doc(desc, in_req_spec, in_opt_spec, out_req_spec, out_opt_spec)}
"""
@spec unquote(
bang_func_typespec(
bang_func_name,
in_req_spec,
in_opt_spec,
out_req_spec,
out_opt_spec
)
)
if in_opt_spec == [] do
# operations without optional arguments
def unquote(bang_func_name)(unquote_splicing(req_params)) do
case __MODULE__.unquote(func_name)(unquote_splicing(req_params)) do
:ok -> :ok
{:ok, result} -> result
{:error, reason} when is_binary(reason) -> raise Error, message: reason
{:error, reason} -> raise Error, message: inspect(reason)
end
end
else
# operations with optional arguments
def unquote(bang_func_name)(unquote_splicing(req_params), optional \\ []) do
case __MODULE__.unquote(func_name)(unquote_splicing(req_params), optional) do
:ok -> :ok
{:ok, result} -> result
{:error, reason} when is_binary(reason) -> raise Error, message: reason
{:error, reason} -> raise Error, message: inspect(reason)
end
end
end
end)
end