Current section

Files

Jump to
dagger lib dagger mod function.ex
Raw

lib/dagger/mod/function.ex

defmodule Dagger.Mod.Function do
@moduledoc false
alias Dagger.Mod.Helper
alias Dagger.Mod.Object
@doc """
Define a Dagger function from the function definition.
"""
@spec define(Dagger.Client.t(), module(), Object.function_def()) :: Dagger.Function.t()
def define(%Dagger.Client{} = dag, module, {name, fun_def}) when is_atom(module) do
args = Keyword.fetch!(fun_def, :args)
return = Keyword.fetch!(fun_def, :return)
dag
|> Dagger.Client.function(
Helper.camelize(name),
define_type(dag, Dagger.Client.type_def(dag), return)
)
|> maybe_with_description(Object.get_function_doc(module, name))
|> with_args(args, dag)
end
defp maybe_with_description(function, nil), do: function
defp maybe_with_description(function, doc), do: Dagger.Function.with_description(function, doc)
defp with_args(fun, args, dag) do
args
|> Enum.reduce(fun, fn {name, arg_def}, fun ->
type = Keyword.fetch!(arg_def, :type)
type_def =
dag
|> define_type(Dagger.Client.type_def(dag), type)
opts =
arg_def
|> Keyword.take([:doc, :default_path, :ignore])
|> Enum.reject(fn {_, value} -> is_nil(value) end)
|> Enum.map(&normalize_arg_option/1)
fun
|> Dagger.Function.with_arg(name, type_def, opts)
end)
end
defp define_type(_dag, type_def, :integer) do
type_def
|> Dagger.TypeDef.with_kind(Dagger.TypeDefKind.integer_kind())
end
defp define_type(_dag, type_def, :float) do
type_def
|> Dagger.TypeDef.with_kind(Dagger.TypeDefKind.float_kind())
end
defp define_type(_dag, type_def, :boolean) do
type_def
|> Dagger.TypeDef.with_kind(Dagger.TypeDefKind.boolean_kind())
end
defp define_type(_dag, type_def, :string) do
type_def
|> Dagger.TypeDef.with_kind(Dagger.TypeDefKind.string_kind())
end
defp define_type(dag, type_def, {:list, type}) do
type_def
|> Dagger.TypeDef.with_list_of(define_type(dag, Dagger.Client.type_def(dag), type))
end
defp define_type(dag, type_def, {:optional, type}) do
dag
|> define_type(type_def, type)
|> Dagger.TypeDef.with_optional(true)
end
defp define_type(_dag, type_def, module) do
case Module.split(module) do
["Dagger", "Void"] ->
type_def
|> Dagger.TypeDef.with_kind(Dagger.TypeDefKind.void_kind())
|> Dagger.TypeDef.with_optional(true)
# A module that generated by codegen.
["Dagger", name] ->
type_def
|> Dagger.TypeDef.with_object(name)
[name] ->
type_def
|> Dagger.TypeDef.with_object(name)
end
end
defp normalize_arg_option({:doc, doc}), do: {:description, doc}
defp normalize_arg_option(opt), do: opt
end