ex_hl7 v1.0.0 HL7.Segment.Spec

Macros and functions used to define HL7 segments

Link to this section Summary

Functions

Builds a specification map based on the field descriptions that were accumulated by the use of the field/2 macro. For a segment defined in the following way

Check that the type of a field in a segment is a base type

Check that the default value of a field in a segment is valid

Check that the length of a field in a segment is valid

Check that the type of a field in a segment is valid

Macro that injects the code used to represent a field within an HL7 segment block. Each field definition looks like the following one

Macro that generates the code that allows a module to be used as an HL7 segment. A segment definition looks like the following block

Link to this section Functions

Link to this function

build_spec(list)

Link to this function

build_spec(fields, segment_id)

build_spec(
  [
    {name :: atom(), seq :: pos_integer(), rep :: pos_integer(), type :: atom(),
     len :: pos_integer()}
  ],
  HL7.Type.segment_id()
) :: map()

Builds a specification map based on the field descriptions that were accumulated by the use of the field/2 macro. For a segment defined in the following way:

require HL7.Composite.Default.CM_ERR_1, as: CM_ERR_1

field :ack_code,           seq: 1, type: :string, len:  2
field :message_control_id, seq: 2, type: :string, len: 20
field :text_message,       seq: 3, type: :string, len: 80
field :error_code,         seq: 6, type: {CM_ERR_1, :error, :id}, len: 10
field :error_text,         seq: 6, type: {CM_ERR_1, :error, :text}, len: 61

This function will end up generating the following segment specification map:

%{
  1 => [{:ack_code, [1], :string, 2}],
  2 => [{:message_control_id, [1], :string, 20}],
  3 => [{:text_message, [1], :string, 80}],
  6 => [[{:error_text, [1, 2], :string, 61}, {:error_code, [1, 1], :string, 10}]]
}

The key in the map corresponds to the field sequence number in the segment, whereas the value is a list of tuples where each tuple has the following elements:

  1. Name: atom with the name of the field this value will be mapped to in the segment.

  2. Index: tuple of integers representing the nested indexes (1-based) where the item is located within the field. The number of elements in the tuple depends on whether the value corresponds to a:

    • field: one element with the field's repetition number (1-based); e.g. {1}.

    • component: two elements with the repetition number and the component index (1-based); e.g. for {CE, :text} you'd get {1, 2}.

    • subcomponent: three elements with the repetition number, the component index and the subcomponent index (1-based); e.g. for {CX, :assigning_authority, :namespace_id} you'd get {1, 4, 1}.

  3. Data type: one of the accepted basic data types (i.e. :string; :integer; :float; :date; :datetime).

  4. Maximum length of the value in bytes.

The tuples in the item spec list will be sorted so that the items that are towards the end of the field end up at the beginning of the list (i.e. reversed). This order acts as an aid when writing the field from the segment map into a buffer.

Examples

A field with these definitions:

field :id,      seq: 3, type: {CX, :id}, len: 6
field :auth_id, seq: 3, type: {CX, :assigning_authority, :namespace_id}, len: 10,
field :id_type, seq: 3, type: {CX, :id_type}, len: 10

Would be expected to have a spec like the following one:

[{:id,      [1, 1],    :string, 6},
 {:auth_id, [1, 4, 1], :string, 10},
 {:id_type, [1, 5],    :string, 10}]

But given that the code that writes the field into a buffer requires this list to be reverse, what is actually returned is the following:

[{:id_type, [1, 5],    :string, 10},
 {:auth_id, [1, 4, 1], :string, 10},
 {:id,      [1, 1],    :string, 6}]
Link to this function

check_base_type!(name, seq, rep, type, segment_id)

Check that the type of a field in a segment is a base type

Link to this function

check_default!(name, seq, rep, type, default, segment_id)

Check that the default value of a field in a segment is valid

Link to this function

check_field!(name, seq, rep, type, default, len, segment_id, acc)

Link to this function

check_length!(name, seq, rep, type, len, segment_id)

Check that the length of a field in a segment is valid

Link to this function

check_name_seq!(name, seq, rep, type, segment_id, fields)

Link to this function

check_type!(name, seq, rep, type, segment_id)

Check that the type of a field in a segment is valid

Link to this macro

field(name, options)

(macro)

Macro that injects the code used to represent a field within an HL7 segment block. Each field definition looks like the following one:

field :diagnosis_type, seq: 6, type: :binary, len: 2

A field has a name that has to be an atom, a seq number (1-based) with the field's position in the segment, a rep indicating the repetition the field corresponds to (1-based), a type, a len and a default value. The default type is :string and the default length is nil. The supported types are:

  • :string
  • :integer
  • :float
  • :date: a field containing a date as a %Date{} struct that is serialized using the YYYYMMDD format.
  • :datetime: a field containing a %NaiveDateTime{} struct that is serialized using the YYYYMMDD[hhmm[ss]] format.
  • an atom corresponding to a composite field's module name. The module must have been built using the macros from the HL7.Composite.Spec module or following the behaviour of an HL7.Composite.
Link to this macro

segment(segment_id, list)

(macro)

Macro that generates the code that allows a module to be used as an HL7 segment. A segment definition looks like the following block:

defmodule HL7.Segment.Default.DG1 do
  require HL7.Composite.Default.CE, as: CE

  segment "DG1" do
    field :set_id,             seq:  1, type: :integer, len: 4
    field :coding_method,      seq:  2, type: :string, len: 2
    field :diagnosis_id,       seq:  3, type: {CE, :id}, len: 20
    field :description,        seq:  4, type: :string, len: 40
    field :diagnosis_datetime, seq:  5, type: :datetime, len: 40
    field :diagnosis_type,     seq:  6, type: :string, len: 2
    field :approval_indicator, seq:  9, type: :string, len: 1
  end
end

A segment has a name or segment ID, which is a binary that will be used to identify the segment when parsing an HL7 message or when converting the segment into its wire format.

Note: when defining a segment, the fields with correlative sequence (seq) numbers need not be in order, but it is recommended that you do so.