Skip to content

Commit 1c28b8f

Browse files
committed
initial commit
0 parents  commit 1c28b8f

File tree

1,081 files changed

+45586
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,081 files changed

+45586
-0
lines changed

coder.go

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package hl7
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"strconv"
7+
"strings"
8+
)
9+
10+
type Registry map[string]any
11+
12+
const tagName = "hl7"
13+
14+
var empty []any
15+
var anyType = reflect.TypeOf(empty).Elem()
16+
17+
type structType byte
18+
19+
const (
20+
structUnknown structType = iota
21+
structTrigger
22+
structTriggerGroup // Trigger Sub-Type
23+
structSegment
24+
structDataType
25+
)
26+
27+
type tag struct {
28+
Order int32
29+
Name string
30+
Format string
31+
Type structType
32+
Meta bool
33+
Child bool
34+
Omit bool
35+
NoEscape bool
36+
Sequence bool
37+
FieldSep bool
38+
FieldChars bool
39+
Present bool
40+
}
41+
42+
const hl7MetaName = "HL7"
43+
44+
func parseTag(fieldName, v string) (tag, error) {
45+
t := tag{}
46+
if len(v) == 0 {
47+
return t, nil
48+
}
49+
t.Present = true
50+
ss := strings.Split(v, ",")
51+
s0 := ss[0]
52+
sN := ss[1:]
53+
if len(s0) > 0 {
54+
i, err := strconv.ParseInt(s0, 10, 32)
55+
if err != nil {
56+
return t, fmt.Errorf("field %q: unable to parse tag position: %w", fieldName, err)
57+
}
58+
t.Order = int32(i)
59+
}
60+
switch fieldName {
61+
case hl7MetaName:
62+
t.Meta = true
63+
}
64+
for _, vv := range sN {
65+
k, v, _ := strings.Cut(vv, "=")
66+
67+
switch k {
68+
default:
69+
return t, fmt.Errorf("field %q: unknown tag value %q", fieldName, vv)
70+
case "name":
71+
t.Name = v
72+
case "type":
73+
switch v {
74+
default:
75+
return t, fmt.Errorf("field %q: unknown type tag value %q", fieldName, vv)
76+
case "t":
77+
t.Type = structTrigger
78+
case "tg":
79+
t.Type = structTriggerGroup
80+
case "s":
81+
t.Type = structSegment
82+
case "d":
83+
t.Type = structDataType
84+
}
85+
case "format":
86+
t.Format = v
87+
case "child":
88+
t.Child = true
89+
case "noescape":
90+
t.NoEscape = true
91+
case "omit":
92+
t.Omit = true
93+
case "seq":
94+
t.Sequence = true
95+
case "required":
96+
// TODO.
97+
case "conditional":
98+
// TODO.
99+
case "len":
100+
// TODO.
101+
case "max":
102+
// TODO.
103+
case "display":
104+
// TODO.
105+
case "table":
106+
// TODO.
107+
case "fieldsep":
108+
t.FieldSep = true
109+
case "fieldchars":
110+
t.FieldChars = true
111+
}
112+
}
113+
return t, nil
114+
}

coder_test.go

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package hl7
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"flag"
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
v25 "github.com/kardianos/hl7/v25"
12+
"github.com/sanity-io/litter"
13+
)
14+
15+
var overwrite = flag.Bool("overwrite", false, "overwrite testing values with got values")
16+
17+
func TestEncode(t *testing.T) {
18+
msg := v25.MSH{
19+
FieldSeparator: `|`,
20+
EncodingCharacters: `^~\&`,
21+
VersionID: v25.VID{
22+
VersionID: "2.5",
23+
},
24+
}
25+
26+
bb, err := Marshal(msg)
27+
if err != nil {
28+
t.Fatal(err)
29+
}
30+
bb = bytes.ReplaceAll(bb, []byte{'\r'}, []byte{'\n'})
31+
t.Log(string(bb))
32+
}
33+
34+
func TestDecode(t *testing.T) {
35+
var raw = []byte(`MSH|^~\&||||||||||2.5^^|||||||||
36+
PID|1||||^Bob||||||||||||||||||||||||||||||||||
37+
NTE|1||testing the system comments here|||
38+
NTE|2||more comments here|||
39+
OBR|1|ABC||||||||||||||1234^Acron^Smith~5678^Beta^Zeta|||||||||||||||||||||||||||||||||||||||||||
40+
OBR|2|XYZ||||||||||||||903^Blacky|||||||||||||||||||||||||||||||||||||||||||`)
41+
42+
v, err := Unmarshal(raw, v25.SegmentRegistry)
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
data, err := json.MarshalIndent(v, "", "\t")
47+
if err != nil {
48+
t.Fatal(err)
49+
}
50+
_ = data
51+
}
52+
func TestGroup(t *testing.T) {
53+
flag.Parse()
54+
var raw = []byte(`MSH|^~\&|DX_LAB|Hematology|WPX||20070305170957||ORL^O34^ORL_O34|2|P|2.5||||||8859/1|||
55+
MSA|AA|161||||
56+
`)
57+
58+
v, err := Unmarshal(raw, v25.SegmentRegistry)
59+
if err != nil {
60+
t.Fatal(err)
61+
}
62+
root, err := Group(v, v25.TriggerRegistry)
63+
if err != nil {
64+
t.Fatal(err)
65+
}
66+
rt, err := Marshal(root)
67+
if err != nil {
68+
t.Fatal(err)
69+
}
70+
rt = bytes.ReplaceAll(rt, []byte{'\r'}, []byte{'\n'})
71+
if bytes.Equal(rt, raw) {
72+
t.Fatal("mismatch")
73+
}
74+
}
75+
76+
func printTypes(t *testing.T, list []any) {
77+
for _, item := range list {
78+
t.Logf("type %T", item)
79+
}
80+
}
81+
82+
func (w *walker) printLinear(t *testing.T) {
83+
for index, item := range w.list {
84+
t.Logf("linear[%d] %s leaf=%t inArray=%t", index, item.Type.String(), item.Leaf, item.InArray)
85+
}
86+
}
87+
88+
func TestRoundTrip(t *testing.T) {
89+
fsDir := filepath.Join("testdata", "roundtrip")
90+
dirList, err := os.ReadDir(fsDir)
91+
if err != nil {
92+
t.Fatal(err)
93+
}
94+
c := &litter.Options{
95+
HideZeroValues: true,
96+
HidePrivateFields: true,
97+
Separator: " ",
98+
}
99+
_ = c
100+
for _, f := range dirList {
101+
if f.IsDir() {
102+
continue
103+
}
104+
t.Run(f.Name(), func(t *testing.T) {
105+
fn := filepath.Join(fsDir, f.Name())
106+
bb, err := os.ReadFile(fn)
107+
if err != nil {
108+
t.Fatal(err)
109+
}
110+
111+
v, err := Unmarshal(bb, v25.SegmentRegistry)
112+
if err != nil {
113+
t.Fatal("unmarshal", err)
114+
}
115+
116+
root, err := Group(v, v25.TriggerRegistry)
117+
if err != nil {
118+
t.Fatal("group", err)
119+
}
120+
121+
rt, err := Marshal(root)
122+
if err != nil {
123+
t.Fatal("marshal", err)
124+
}
125+
rt = bytes.ReplaceAll(rt, []byte{'\r'}, []byte{'\n'})
126+
if *overwrite {
127+
os.WriteFile(fn, rt, 0600)
128+
}
129+
d := lineDiff(bb, rt)
130+
if len(d) > 0 {
131+
t.Fatalf("mismatch\n%s", d)
132+
}
133+
})
134+
}
135+
}

0 commit comments

Comments
 (0)