Skip to content

Commit

Permalink
refactor to find_in_segment only
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkMarmot committed Mar 25, 2024
1 parent a6fb3a3 commit a067cd3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 61 deletions.
17 changes: 15 additions & 2 deletions lib/hl7/hpath.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ defmodule HL7.HPath do
component: nil,
subcomponent: nil,
truncate: false,
precision: nil
precision: nil,
indices: nil

@doc ~S"""
The `~HP` sigil encodes an HL7 path into a struct at compile-time to guarantee correctness and speed.
Expand Down Expand Up @@ -72,7 +73,8 @@ defmodule HL7.HPath do
|> Map.merge(Map.new(data, fn {k, v} -> {k, hd(v)} end))

path_map
|> Map.put(:precision, get_precision(path_map))
|> then(&Map.put(&1, :precision, get_precision(&1)))
|> then(&Map.put(&1, :indices, get_indices(&1)))
|> Macro.escape()
end

Expand All @@ -85,4 +87,15 @@ defmodule HL7.HPath do
true -> :segment
end
end

defp get_indices(%__MODULE__{} = path_map) do
# case path_map.precision do
# :segment -> []
# :field -> [path_map.field]
# :repetition -> [path_map.field, path_map.repetition]
# :component -> [path_map.field, path_map.repetition, path_map.component]
# :subcomponent -> [path_map.field, path_map.repetition, path_map.component, path_map.subcomponent]
# end
[path_map.field, path_map.repetition, path_map.component, path_map.subcomponent]
end
end
95 changes: 36 additions & 59 deletions lib/hl7/maps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -211,100 +211,77 @@ defmodule HL7.Maps do
|> Enum.reverse()
end

defp find_in_segment(segment, %HPath{field: nil} = _hpath) do
segment
defp get_index_value(segment_data, 1) when is_binary(segment_data) do
segment_data
end

defp find_in_segment(segment, %HPath{field: f} = hpath) do
find_in_field(segment[f], hpath)
defp get_index_value(segment_data, nil) when is_binary(segment_data) do
segment_data
end

defp find_in_field(field, %HPath{repetition: "*", component: nil}) when is_binary(field) do
[field]
end

defp find_in_field(field, %HPath{repetition: "*", component: _}) when is_binary(field) do
[]
end

defp find_in_field(nil, %HPath{repetition: "*"}) do
[]
end

defp find_in_field(field, %HPath{repetition: "*"} = hpath) when is_map(field) do
1..field[:e] |> Enum.map(fn i -> find_in_repetition(field[i], hpath) end)
end

defp find_in_field(field, %HPath{repetition: 1, component: nil}) when is_binary(field) do
field
end

defp find_in_field(field, %HPath{repetition: 1, component: 1}) when is_binary(field) do
field
end

defp find_in_field(field, %HPath{repetition: 1, component: _}) when is_binary(field) do
defp get_index_value(segment_data, _) when is_binary(segment_data) do
nil
end

defp find_in_field(field, %HPath{repetition: r} = hpath) when is_map_key(field, r) do
find_in_repetition(field[r], hpath)
end

defp find_in_field(_field, _hpath) do
defp get_index_value(%{e: e} = _segment_data, i) when i > e do
nil
end

defp find_in_repetition(nil, _hpath) do
nil
defp get_index_value(segment_data, i) do
Map.get(segment_data, i, "")
end

defp find_in_repetition(repetition, %HPath{component: 1}) when is_binary(repetition) do
repetition
defp truncate(segment_data) when is_binary(segment_data) or is_nil(segment_data) do
segment_data
end

defp find_in_repetition(repetition, %HPath{component: _}) when is_binary(repetition) do
nil
defp truncate(segment_data) when is_map(segment_data) do
get_index_value(segment_data, 1)
|> truncate()
end

defp find_in_repetition(repetition, %HPath{truncate: true} = hpath) do
find_in_component(repetition[1], hpath)
defp find_in_segment(segment, hpath) do
find_in_segment(segment, hpath, hpath.indices)
end

defp find_in_repetition(repetition, %HPath{component: nil}) do
repetition
defp find_in_segment(segment_data, %HPath{truncate: true}, []) do
truncate(segment_data)
end

defp find_in_repetition(repetition, %HPath{component: c, subcomponent: nil}) do
repetition[c]
defp find_in_segment(segment_data, %HPath{truncate: false}, []) do
segment_data
end

defp find_in_repetition(repetition, %HPath{component: c, subcomponent: _} = hpath) do
find_in_component(repetition[c], hpath)
defp find_in_segment(segment_data, _hpath, ["*"]) when is_binary(segment_data) do
[segment_data]
end

defp find_in_component(component, %HPath{truncate: true}) when is_binary(component) do
component
defp find_in_segment(segment_data, _hpath, ["*" | remaining_indices]) when is_binary(segment_data) do
if Enum.all?(remaining_indices, fn i -> i in [1, nil] end), do: [segment_data], else: [nil]
end

defp find_in_component(component, %HPath{truncate: true}) do
component[1]
defp find_in_segment(segment_data, hpath, [1 | remaining_indices]) when is_binary(segment_data) do
find_in_segment(segment_data, hpath, remaining_indices)
end

defp find_in_component(component, %HPath{subcomponent: 1}) when is_binary(component) do
component
defp find_in_segment(segment_data, _hpath, [nil | _remaining_indices]) when is_binary(segment_data) do
segment_data
end

defp find_in_component(component, %HPath{subcomponent: _}) when is_binary(component) do
defp find_in_segment(segment_data, _hpath, [_ | _remaining_indices]) when is_binary(segment_data) do
nil
end

defp find_in_component(component, %HPath{subcomponent: nil}) do
component
defp find_in_segment(segment_data, hpath, ["*" | remaining_indices]) do
1..segment_data[:e] |> Enum.map(fn i -> find_in_segment(get_index_value(segment_data, i), hpath, remaining_indices) end)
end

defp find_in_segment(segment_data, hpath, [nil | _remaining_indices]) do
find_in_segment(segment_data, hpath, [])
end

defp find_in_component(component, %HPath{subcomponent: s}) do
component[s]
defp find_in_segment(segment_data, hpath, [i | remaining_indices]) do
find_in_segment(get_index_value(segment_data, i), hpath, remaining_indices)
end

defp do_label(segment_data, %HPath{} = output_param) do
Expand Down

0 comments on commit a067cd3

Please sign in to comment.