# `Unifex.CodeGenerator.BaseType`
[🔗](https://github.com/membraneframework/unifex/blob/v1.2.5/lib/unifex/code_generator/base_type.ex#L1)

Behaviour and abstraction over type-specific code generation.

When invoking callbacks for type `:type` and interface `Interface` it searches for
a module that implements given callback in the following order:
- `Unifex.CodeGenerator.BaseTypes.Type.Interface`
- `Unifex.CodeGenerator.BaseTypes.Type`
- `Unifex.CodeGenerator.BaseTypes.Default.Interface`

# `arg_parse_ctx_t`

```elixir
@type arg_parse_ctx_t() :: %{
  result_var: Unifex.CodeGenerator.code_t(),
  exit_label: Unifex.CodeGenerator.code_t()
}
```

# `t`

```elixir
@type t() :: atom() | {:list, atom()}
```

# `generate_arg_parse`
*optional* 

```elixir
@callback generate_arg_parse(
  argument :: Unifex.CodeGenerator.code_t(),
  variable :: Unifex.CodeGenerator.code_t(),
  ctx :: map()
) :: Unifex.CodeGenerator.code_t()
```

Generates function call parsing UNIFEX_TERM `argument` into the native variable with name `variable`. Function should
return boolean value.

# `generate_arg_serialize`
*optional* 

```elixir
@callback generate_arg_serialize(name :: atom(), ctx :: map()) ::
  Unifex.CodeGenerator.code_t()
```

Provides a way to convert native variable `name` into `UNIFEX_TERM`

# `generate_destruction`
*optional* 

```elixir
@callback generate_destruction(name :: atom(), ctx :: map()) ::
  Unifex.CodeGenerator.code_t()
```

Generates a destruction of variable content. Should be paired with `c:generate_initialization/2`

# `generate_initialization`
*optional* 

```elixir
@callback generate_initialization(name :: atom(), ctx :: map()) ::
  Unifex.CodeGenerator.code_t()
```

Generates an initialization of variable content. Should be paired with `c:generate_destruction/2`

# `generate_native_type`
*optional* 

```elixir
@callback generate_native_type(ctx :: map()) ::
  Unifex.CodeGenerator.code_t() | [Unifex.CodeGenerator.code_t()]
```

Generates a native counterpart for the type.

# `ptr_level`
*optional* 

```elixir
@callback ptr_level(ctx :: map()) :: integer()
```

Returns level of pointer nesting of native type.

# `generate_arg_name`

```elixir
@spec generate_arg_name(t(), name :: atom(), Unifex.CodeGenerator.t(), map()) :: [
  Unifex.CodeGenerator.code_t()
]
```

# `generate_arg_parse`

```elixir
@spec generate_arg_parse(
  t(),
  name :: atom(),
  argument :: Unifex.CodeGenerator.code_t(),
  (Unifex.CodeGenerator.code_t() -&gt; Unifex.CodeGenerator.code_t()),
  Unifex.CodeGenerator.t(),
  map()
) :: Unifex.CodeGenerator.code_t()
```

Generates parsing of UNIFEX_TERM `argument` into the native variable

# `generate_arg_serialize`

```elixir
@spec generate_arg_serialize(
  t(),
  name :: atom(),
  Unifex.CodeGenerator.t(),
  ctx :: map()
) ::
  Unifex.CodeGenerator.code_t()
```

Provides a way to convert native variable `name` into `UNIFEX_TERM`

Tries to get value from type-specific module, uses `enif_make_#{type}` as fallback value.

# `generate_declaration`

```elixir
@spec generate_declaration(
  t(),
  name :: atom(),
  mode :: :default | :const | :const_unless_ptr_on_ptr,
  Unifex.CodeGenerator.t(),
  ctx :: map()
) :: [Unifex.CodeGenerator.code_t()]
```

Generates a declaration of parameter (to be placed in function header) based on `c:generate_native_type/1` and
provided `name`.

Uses `type` as fallback for `c:generate_native_type/1`

When mode is set to :const_unless_ptr_on_ptr, function will choose to behave like it would be set to :default or :const,
depending on value returned by `ptr_level(type, code_generator, ctx)`.
This mode can be used in places, when in general, you want to have declaration of variable with const type, but using :const
mode would generate code, that would require explicit cast to avoid generating warnings during compilation - e.g. in C,
passing argument of type `char **` to function, that expects argument of type `char const * const *` without any explicit cast,
will generate such a warning

# `generate_destruction`

```elixir
@spec generate_destruction(
  t(),
  name :: atom(),
  Unifex.CodeGenerator.t(),
  ctx :: map()
) ::
  Unifex.CodeGenerator.code_t()
```

Generates an destrucition of variable content. Should be paired with `generate_initialization/1`

Returns an empty string if the type does not provide destructor

# `generate_initialization`

```elixir
@spec generate_initialization(
  t(),
  name :: atom(),
  Unifex.CodeGenerator.t(),
  ctx :: map()
) ::
  Unifex.CodeGenerator.code_t()
```

Generates an initialization of variable content. Should be paired with `generate_destruction/1`

Returns an empty string if the type does not provide initialization

# `generate_native_type`

```elixir
@spec generate_native_type(t(), :const | :default, Unifex.CodeGenerator.t(), map()) ::
  Unifex.CodeGenerator.code_t()
```

# `ptr_level`

```elixir
@spec ptr_level(t(), Unifex.CodeGenerator.t(), ctx :: map()) :: integer()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
