func (hd *HD) String() string {
	if hd == nil {
		return ""
	}
	c := &Context{
		Decoder:     unicode.UTF8.NewDecoder(),
		Delimiters:  DefaultDelimiters,
		Nesting:     0,
		TimezoneLoc: Location,
	}
	b, err := marshalCompositeValue(reflect.ValueOf(*hd), c)
	if err != nil {
		return "unable to marshal HD"
	}
	return string(b)
}
HD (Hierarchic designator) helper functions.
package hl7
import (
	"bytes"
	"errors"
	"reflect"
	"strconv"
	"time"
	"golang.org/x/text/encoding/unicode"
)
type ST string
var _ Primitive = (*ST)(nil)
func NewST(st ST) *ST {
	return &st
}
func (st *ST) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*st)), nil
}
func (st *ST) Unmarshal(field []byte, c *Context) error {
	parsed, err := parseText(field, c)
	if err != nil {
		*st = ""
		return err
	}
	*st = ST(parsed)
	return nil
}
func SanitizeString(s string) string {
	if isHL7Null([]byte(s)) {
		return ""
	}
	return s
}
func (st *ST) SanitizedString() string {
	return SanitizeString(st.String())
}
func (st *ST) String() string {
	if st == nil {
		return ""
	}
	return string(*st)
}
func (st *ST) Empty() bool {
	return st == nil || *st == ""
}
type ID string
var _ Primitive = (*ID)(nil)
func NewID(id ID) *ID {
	return &id
}
func (id *ID) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*id)), nil
}
func (id *ID) Unmarshal(field []byte, _ *Context) error {
	*id = ID(field)
	return nil
}
func (id *ID) SanitizedString() string {
	return SanitizeString(id.String())
}
func (id *ID) String() string {
	if id == nil {
		return ""
	}
	return string(*id)
}
func (id *ID) Empty() bool {
	return id == nil || *id == ""
}
type SI struct {
	Value uint64
	Valid bool  
}
var _ Primitive = (*SI)(nil)
func NewSI(value uint64) *SI {
	return &SI{value, true}
}
func (si *SI) Marshal(_ *Context) ([]byte, error) {
	return []byte(strconv.FormatUint(si.Value, 10)), nil
}
func (si *SI) Unmarshal(field []byte, _ *Context) error {
	si.Valid = !isHL7Null(field)
	if !si.Valid {
		return nil
	}
	i, err := strconv.ParseInt(string(field), 10, 64)
	if err != nil {
		err = ErrBadValue
	} else if i < 0 {
		err = errors.New("SI must be non-negative")
	} else {
		si.Value = uint64(i)
	}
	return err
}
type NM struct {
	Value float64
	Valid bool  
}
var _ Primitive = (*NM)(nil)
func NewNM(value float64) *NM {
	return &NM{Value: value, Valid: true}
}
func (nm *NM) Marshal(_ *Context) ([]byte, error) {
	return []byte(strconv.FormatFloat(nm.Value, 'f', -1, 64)), nil
}
func (nm *NM) Unmarshal(field []byte, _ *Context) error {
	nm.Valid = !isHL7Null(field)
	if !nm.Valid {
		return nil
	}
	i, err := strconv.ParseFloat(string(field), 64)
	if err != nil {
		return ErrBadValue
	}
	nm.Value = i
	return nil
}
type IS string
var _ Primitive = (*IS)(nil)
func NewIS(is IS) *IS {
	return &is
}
func (is *IS) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*is)), nil
}
func (is *IS) Unmarshal(field []byte, _ *Context) error {
	*is = IS(field)
	return nil
}
func (is *IS) SanitizedString() string {
	return SanitizeString(is.String())
}
func (is *IS) String() string {
	if is == nil {
		return ""
	}
	return string(*is)
}
func (is *IS) Empty() bool {
	return is == nil || *is == ""
}
type DT string
var _ Primitive = (*DT)(nil)
func NewDT(dt DT) *DT {
	return &dt
}
func (dt *DT) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*dt)), nil
}
func (dt *DT) Unmarshal(field []byte, _ *Context) error {
	*dt = DT(field)
	return nil
}
type TM string
var _ Primitive = (*TM)(nil)
func NewTM(tm TM) *TM {
	return &tm
}
func (tm *TM) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*tm)), nil
}
func (tm *TM) Unmarshal(field []byte, _ *Context) error {
	*tm = TM(field)
	return nil
}
type TSPrecision int
const (
	YearPrecision TSPrecision = iota
	MonthPrecision
	DayPrecision
	HourPrecision
	MinutePrecision
	SecondPrecision
	TenthSecondPrecision
	HundredthSecondPrecision
	ThousandthSecondPrecision
	TenThousandthSecondPrecision
)
func (p TSPrecision) formatString() string {
	return [...]string{
		"2006",
		"200601",
		"20060102",
		"2006010215",
		"200601021504",
		"20060102150405",
		"20060102150405.0",
		"20060102150405.00",
		"20060102150405.000",
		"20060102150405.0000",
	}[p]
}
type TS struct {
	IsHL7Null     bool
	Time          time.Time
	Precision     TSPrecision
	ElideTimezone bool
}
var _ Primitive = (*TS)(nil)
func (ts *TS) Marshal(c *Context) ([]byte, error) {
	time := ts.Time.In(c.TimezoneLoc)
	format := ts.Precision.formatString()
	if c.IncludeTimezone && !ts.ElideTimezone {
		format += "-0700"
	}
	return []byte(time.Format(format)), nil
}
func (ts *TS) Unmarshal(field []byte, c *Context) error {
	ts.IsHL7Null = isHL7Null(field)
	if ts.IsHL7Null {
		return nil
	}
	components := c.Delimiters.splitComponents(Token{Value: field}, c.Nesting)
	var tsWithoutTz []byte
	tzIndex := bytes.LastIndexAny(components[0].Value, "+-")
	if tzIndex > 0 {
		tsWithoutTz = components[0].Value[0:tzIndex]
	} else {
		tsWithoutTz = components[0].Value
	}
	var format string
	switch len(tsWithoutTz) {
	case 4:
		format = "2006"
		ts.Precision = YearPrecision
	case 6:
		format = "200601"
		ts.Precision = MonthPrecision
	case 8:
		format = "20060102"
		ts.Precision = DayPrecision
	case 10:
		format = "2006010215"
		ts.Precision = HourPrecision
	case 12:
		format = "200601021504"
		ts.Precision = MinutePrecision
	case 14:
		format = "20060102150405"
		ts.Precision = SecondPrecision
	case 16:
		format = "20060102150405.0"
		ts.Precision = TenthSecondPrecision
	case 17:
		format = "20060102150405.00"
		ts.Precision = HundredthSecondPrecision
	case 18:
		format = "20060102150405.000"
		ts.Precision = ThousandthSecondPrecision
	case 19:
		format = "20060102150405.0000"
		ts.Precision = TenThousandthSecondPrecision
	default:
		return errors.New("bad TS value: invalid length")
	}
	if len(components) > 1 {
		switch string(components[1].Value) {
		case "Y":
			ts.Precision = YearPrecision
		case "L":
			ts.Precision = MonthPrecision
		case "D":
			ts.Precision = DayPrecision
		case "H":
			ts.Precision = HourPrecision
		case "M":
			ts.Precision = MinutePrecision
		case "S":
			ts.Precision = SecondPrecision
		default:
			return errors.New("bad TS value: unknown precision")
		}
	}
	var err error
	if tzIndex < 0 && ts.Precision > DayPrecision {
		ts.Time, err = time.ParseInLocation(format, string(tsWithoutTz), c.TimezoneLoc)
		return err
	}
	if tzIndex < 0 && ts.Precision <= DayPrecision {
		ts.Time, err = time.Parse(format, string(tsWithoutTz))
		return err
	}
	ts.Time, err = time.Parse(format+"-0700", string(components[0].Value))
	return err
}
type TN string
var _ Primitive = (*TN)(nil)
func NewTN(tn TN) *TN {
	return &tn
}
func (tn *TN) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*tn)), nil
}
func (tn *TN) Unmarshal(field []byte, _ *Context) error {
	*tn = TN(field)
	return nil
}
type FT string
var _ Primitive = (*FT)(nil)
func NewFT(ft FT) *FT {
	return &ft
}
func (ft *FT) Marshal(c *Context) ([]byte, error) {
	return marshalText([]byte(*ft), c), nil
}
func (ft *FT) Unmarshal(field []byte, c *Context) error {
	parsed, err := parseText(field, c)
	if err != nil {
		*ft = ""
		return err
	}
	*ft = FT(parsed)
	return nil
}
type TX string
var _ Primitive = (*TX)(nil)
func NewTX(tx TX) *TX {
	return &tx
}
func (tx *TX) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*tx)), nil
}
func (tx *TX) Unmarshal(field []byte, _ *Context) error {
	*tx = TX(field)
	return nil
}
func (hd *HD) SanitizedString() string {
	return SanitizeString(hd.String())
}