# `HL7v2.Type`
[🔗](https://github.com/Balneario-de-Cofrentes/hl7v2/blob/v3.10.1/lib/hl7v2/type.ex#L1)

Base behaviour for HL7v2 data types.

Every data type module (primitive and composite) implements this behaviour,
providing `parse/1` and `encode/1` for converting between wire-format
representations and typed Elixir values.

Primitive types (ST, NM, DT, etc.) work with binaries.
Composite types (CX, XPN, HD, etc.) work with lists of component strings
and return/accept structs.

## Sub-Component Separator

By default, sub-component fields are split/joined with `&`. When a message
declares a non-default sub-component separator (e.g., `$` in MSH-2 `^~\$`),
call `with_sub_component_separator/2` to set it for the duration of a
parse or encode operation. Composite types read the active separator via
`sub_component_separator/0`.

# `encode`

```elixir
@callback encode(struct() | binary() | nil) :: list() | binary()
```

Encodes a typed Elixir value back to wire format.

# `parse`

```elixir
@callback parse(list() | binary()) :: struct() | binary() | nil
```

Parses a wire-format value into a typed Elixir value.

# `all_nil?`

```elixir
@spec all_nil?(struct()) :: boolean()
```

Returns `true` if every field in the given struct is `nil`.

Used after parsing a sub-component to decide whether the result is
effectively empty and should be returned as `nil`.

## Examples

    iex> HL7v2.Type.all_nil?(%HL7v2.Type.HD{})
    true

    iex> HL7v2.Type.all_nil?(%HL7v2.Type.HD{namespace_id: "MRN"})
    false

# `encode_sub`

```elixir
@spec encode_sub(module(), struct() | nil) :: binary()
```

Encodes a sub-component struct back to a sub-component-separated string.

Delegates to `module.encode/1` and joins the result with the active
sub-component separator.

Returns `""` for `nil` input.

## Examples

    iex> HL7v2.Type.encode_sub(HL7v2.Type.HD, %HL7v2.Type.HD{namespace_id: "MRN", universal_id: "1.2.3", universal_id_type: "ISO"})
    "MRN&1.2.3&ISO"

    iex> HL7v2.Type.encode_sub(HL7v2.Type.HD, nil)
    ""

# `encode_sub_ts`

```elixir
@spec encode_sub_ts(HL7v2.Type.TS.t() | HL7v2.Type.DTM.t() | nil) :: binary()
```

Encodes a sub-component TS or DTM value to a sub-component-separated string.

Handles both `%TS{}` structs (encoded as sub-component list) and bare
`%DTM{}` structs (encoded directly as a date-time string).

Returns `""` for `nil` input.

## Examples

    iex> HL7v2.Type.encode_sub_ts(%HL7v2.Type.TS{time: %HL7v2.Type.DTM{year: 2026, month: 3, day: 22}})
    "20260322"

    iex> HL7v2.Type.encode_sub_ts(%HL7v2.Type.DTM{year: 2026, month: 3, day: 22})
    "20260322"

    iex> HL7v2.Type.encode_sub_ts(nil)
    ""

# `get_component`

```elixir
@spec get_component(list(), non_neg_integer()) :: binary() | nil
```

Extracts a string value from a component, returning `nil` for empty/nil inputs.

Used internally by composite type parsers to normalize component access.

# `pad_components`

```elixir
@spec pad_components(list(), non_neg_integer()) :: list()
```

Pads a list of components to the given length with nils.

# `parse_sub`

```elixir
@spec parse_sub(module(), binary() | nil) :: struct() | nil
```

Parses a sub-component string into the given composite type's struct.

Splits `value` on the active sub-component separator, delegates to
`module.parse/1`, and returns `nil` if all fields in the resulting
struct are `nil`.

Returns `nil` for `nil` input.

## Examples

    iex> HL7v2.Type.parse_sub(HL7v2.Type.HD, "MRN&1.2.3&ISO")
    %HL7v2.Type.HD{namespace_id: "MRN", universal_id: "1.2.3", universal_id_type: "ISO"}

    iex> HL7v2.Type.parse_sub(HL7v2.Type.HD, nil)
    nil

# `parse_sub_ts`

```elixir
@spec parse_sub_ts(binary() | nil) :: HL7v2.Type.TS.t() | nil
```

Parses a sub-component TS (Time Stamp) value.

Like `parse_sub/2` but uses the TS-specific nil check: a TS is
considered nil when both `time` and `degree_of_precision` are nil.

## Examples

    iex> HL7v2.Type.parse_sub_ts("20260322143000")
    %HL7v2.Type.TS{time: %HL7v2.Type.DTM{year: 2026, month: 3, day: 22, hour: 14, minute: 30, second: 0}}

    iex> HL7v2.Type.parse_sub_ts(nil)
    nil

# `sub_component_separator`

```elixir
@spec sub_component_separator() :: binary()
```

Returns the active sub-component separator string.

Defaults to `"&"` when no separator context has been set via
`with_sub_component_separator/2`.

# `trim_trailing`

```elixir
@spec trim_trailing(list()) :: list()
```

Trims trailing nil/empty values from a list of components for compact encoding.

# `with_sub_component_separator`

```elixir
@spec with_sub_component_separator(binary(), (-&gt; result)) :: result
when result: term()
```

Executes `fun` with the given sub-component separator active.

The separator is stored in the process dictionary for the duration of `fun`
and restored to its previous value afterwards. This is used by segment
parse/encode to propagate the message's actual sub-component delimiter to
all composite type helpers.

---

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