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
build_spec(list)
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:
Name: atom with the name of the field this value will be mapped to in the segment.
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}.
Data type: one of the accepted basic data types (i.e.
:string
;:integer
;:float
;:date
;:datetime
).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}]
check_base_type!(name, seq, rep, type, segment_id)
Check that the type of a field in a segment is a base type
check_default!(name, seq, rep, type, default, segment_id)
Check that the default value of a field in a segment is valid
check_field!(name, seq, rep, type, default, len, segment_id, acc)
check_length!(name, seq, rep, type, len, segment_id)
Check that the length of a field in a segment is valid
check_name_seq!(name, seq, rep, type, segment_id, fields)
check_type!(name, seq, rep, type, segment_id)
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:
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 theYYYYMMDD
format.:datetime
: a field containing a%NaiveDateTime{}
struct that is serialized using theYYYYMMDD[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 anHL7.Composite
.
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.