Skip to content

Types Package

The github.com/gofhir/fhirpath/types package defines the FHIRPath type system. Every value returned by a FHIRPath evaluation is a Value, and every evaluation result is a Collection (an ordered slice of Value). This page documents all interfaces, types, and their methods.

import "github.com/gofhir/fhirpath/types"

Core Interfaces

Value

The base interface for all FHIRPath values. Every type in this package implements Value.

type Value interface {
    // Type returns the FHIRPath type name (e.g., "Boolean", "Integer", "String").
    Type() string

    // Equal compares exact equality (the = operator in FHIRPath).
    Equal(other Value) bool

    // Equivalent compares equivalence (the ~ operator in FHIRPath).
    // For strings: case-insensitive, normalized whitespace.
    Equivalent(other Value) bool

    // String returns a human-readable string representation of the value.
    String() string

    // IsEmpty indicates if this value represents an empty value.
    IsEmpty() bool
}

Comparable

Implemented by types that support ordering (less than, greater than). Extends Value.

type Comparable interface {
    Value
    // Compare returns -1 if less than, 0 if equal, 1 if greater than.
    // Returns error if types are incompatible.
    Compare(other Value) (int, error)
}

Types that implement Comparable: Integer, Decimal, String, Date, DateTime, Time, Quantity.

Numeric

Implemented by numeric types. Provides a conversion to Decimal for cross-type arithmetic.

type Numeric interface {
    Value
    // ToDecimal converts the numeric value to a Decimal.
    ToDecimal() Decimal
}

Types that implement Numeric: Integer, Decimal.


Collection

Collection is the fundamental return type for all FHIRPath expressions. It is an ordered sequence of Value elements.

type Collection []Value

Querying Methods

Empty

Returns true if the collection has no elements.

func (c Collection) Empty() bool

Count

Returns the number of elements.

func (c Collection) Count() int

First

Returns the first element and true, or nil and false if the collection is empty.

func (c Collection) First() (Value, bool)

Last

Returns the last element and true, or nil and false if the collection is empty.

func (c Collection) Last() (Value, bool)

Single

Returns the single element if the collection has exactly one element. Returns an error if the collection is empty or has more than one element.

func (c Collection) Single() (Value, error)

Contains

Returns true if the collection contains a value equal to v (using Equal).

func (c Collection) Contains(v Value) bool

Subsetting Methods

Tail

Returns all elements except the first.

func (c Collection) Tail() Collection

Skip

Returns a new collection with the first n elements removed.

func (c Collection) Skip(n int) Collection

Take

Returns a new collection with only the first n elements.

func (c Collection) Take(n int) Collection

Set Operations

Distinct

Returns a new collection with duplicate values removed, preserving the order of first occurrence.

func (c Collection) Distinct() Collection

IsDistinct

Returns true if all elements in the collection are unique.

func (c Collection) IsDistinct() bool

Union

Returns the union of two collections with duplicates removed.

func (c Collection) Union(other Collection) Collection

Combine

Returns a new collection that concatenates both collections. Unlike Union, duplicates are preserved.

func (c Collection) Combine(other Collection) Collection

Intersect

Returns elements that exist in both collections.

func (c Collection) Intersect(other Collection) Collection

Exclude

Returns elements in c that are not in other.

func (c Collection) Exclude(other Collection) Collection

Boolean Aggregation

AllTrue

Returns true if every element is a Boolean with value true. Returns true for an empty collection (vacuous truth).

func (c Collection) AllTrue() bool

AnyTrue

Returns true if at least one element is a Boolean with value true.

func (c Collection) AnyTrue() bool

AllFalse

Returns true if every element is a Boolean with value false. Returns true for an empty collection.

func (c Collection) AllFalse() bool

AnyFalse

Returns true if at least one element is a Boolean with value false.

func (c Collection) AnyFalse() bool

Conversion

ToBoolean

Converts a singleton Boolean collection to a Go bool. Returns an error if the collection is empty, has more than one element, or the single element is not a Boolean.

func (c Collection) ToBoolean() (bool, error)

String

Returns a string representation of the collection in the form [val1, val2, ...].

func (c Collection) String() string

Collection Example

import "github.com/gofhir/fhirpath/types"

c := types.Collection{
    types.NewString("alpha"),
    types.NewString("beta"),
    types.NewString("gamma"),
}

fmt.Println(c.Count())       // 3
fmt.Println(c.Empty())       // false

first, ok := c.First()
fmt.Println(first, ok)       // alpha true

tail := c.Tail()
fmt.Println(tail)            // [beta, gamma]

top2 := c.Take(2)
fmt.Println(top2)            // [alpha, beta]

without1 := c.Skip(1)
fmt.Println(without1)        // [beta, gamma]

single, err := c.Take(1).Single()
fmt.Println(single, err)     // alpha <nil>

Boolean

Represents a FHIRPath boolean value (true or false).

type Boolean struct {
    // unexported fields
}

Implements: Value

NewBoolean

func NewBoolean(v bool) Boolean

Key Methods

MethodSignatureDescription
Boolfunc (b Boolean) Bool() boolReturns the underlying bool value
Notfunc (b Boolean) Not() BooleanReturns the logical negation
Typefunc (b Boolean) Type() stringReturns "Boolean"
Stringfunc (b Boolean) String() stringReturns "true" or "false"

Example:

t := types.NewBoolean(true)
f := t.Not()

fmt.Println(t.Bool())   // true
fmt.Println(f.Bool())   // false
fmt.Println(t.Type())   // Boolean
fmt.Println(t.Equal(f)) // false

Integer

Represents a FHIRPath integer value (backed by int64).

type Integer struct {
    // unexported fields
}

Implements: Value, Comparable, Numeric

NewInteger

func NewInteger(v int64) Integer

Key Methods

MethodSignatureDescription
Valuefunc (i Integer) Value() int64Returns the underlying int64
ToDecimalfunc (i Integer) ToDecimal() DecimalConverts to Decimal
Addfunc (i Integer) Add(other Integer) IntegerAddition
Subtractfunc (i Integer) Subtract(other Integer) IntegerSubtraction
Multiplyfunc (i Integer) Multiply(other Integer) IntegerMultiplication
Dividefunc (i Integer) Divide(other Integer) (Decimal, error)Division (returns Decimal)
Divfunc (i Integer) Div(other Integer) (Integer, error)Integer division
Modfunc (i Integer) Mod(other Integer) (Integer, error)Modulo
Negatefunc (i Integer) Negate() IntegerNegation
Absfunc (i Integer) Abs() IntegerAbsolute value
Powerfunc (i Integer) Power(exp Integer) DecimalExponentiation (returns Decimal)
Sqrtfunc (i Integer) Sqrt() (Decimal, error)Square root (returns Decimal)
Comparefunc (i Integer) Compare(other Value) (int, error)Comparison (works with Integer and Decimal)

Example:

a := types.NewInteger(10)
b := types.NewInteger(3)

fmt.Println(a.Add(b).Value())       // 13
fmt.Println(a.Subtract(b).Value())  // 7
fmt.Println(a.Multiply(b).Value())  // 30

div, _ := a.Div(b)
fmt.Println(div.Value())            // 3

mod, _ := a.Mod(b)
fmt.Println(mod.Value())            // 1

result, _ := a.Divide(b)
fmt.Println(result)                 // 3.3333333333333333

Decimal

Represents a FHIRPath decimal value with arbitrary precision (backed by github.com/shopspring/decimal).

type Decimal struct {
    // unexported fields
}

Implements: Value, Comparable, Numeric

Constructors

FunctionSignatureDescription
NewDecimalfunc NewDecimal(s string) (Decimal, error)Creates from a string like "3.14"
NewDecimalFromIntfunc NewDecimalFromInt(v int64) DecimalCreates from an int64
NewDecimalFromFloatfunc NewDecimalFromFloat(v float64) DecimalCreates from a float64
MustDecimalfunc MustDecimal(s string) DecimalLike NewDecimal, panics on error

Key Methods

MethodSignatureDescription
Valuefunc (d Decimal) Value() decimal.DecimalReturns the underlying decimal.Decimal
ToDecimalfunc (d Decimal) ToDecimal() DecimalReturns itself
Addfunc (d Decimal) Add(other Decimal) DecimalAddition
Subtractfunc (d Decimal) Subtract(other Decimal) DecimalSubtraction
Multiplyfunc (d Decimal) Multiply(other Decimal) DecimalMultiplication
Dividefunc (d Decimal) Divide(other Decimal) (Decimal, error)Division (16-digit precision)
Negatefunc (d Decimal) Negate() DecimalNegation
Absfunc (d Decimal) Abs() DecimalAbsolute value
Ceilingfunc (d Decimal) Ceiling() IntegerSmallest integer >= d
Floorfunc (d Decimal) Floor() IntegerLargest integer <= d
Truncatefunc (d Decimal) Truncate() IntegerInteger part
Roundfunc (d Decimal) Round(precision int32) DecimalRound to precision
Powerfunc (d Decimal) Power(exp Decimal) DecimalExponentiation
Sqrtfunc (d Decimal) Sqrt() (Decimal, error)Square root
Expfunc (d Decimal) Exp() Decimale^d
Lnfunc (d Decimal) Ln() (Decimal, error)Natural logarithm
Logfunc (d Decimal) Log(base Decimal) (Decimal, error)Logarithm with custom base
IsIntegerfunc (d Decimal) IsInteger() boolTrue if no fractional part
ToIntegerfunc (d Decimal) ToInteger() (Integer, bool)Convert to Integer if whole number
Comparefunc (d Decimal) Compare(other Value) (int, error)Comparison (works with Integer and Decimal)

Example:

pi, _ := types.NewDecimal("3.14159")
two := types.NewDecimalFromInt(2)

fmt.Println(pi.Add(two))           // 5.14159
fmt.Println(pi.Multiply(two))      // 6.28318
fmt.Println(pi.Round(2))           // 3.14
fmt.Println(pi.Ceiling())          // 4
fmt.Println(pi.Floor())            // 3
fmt.Println(pi.IsInteger())        // false

// MustDecimal for constants
half := types.MustDecimal("0.5")
fmt.Println(half)                  // 0.5

String

Represents a FHIRPath string value.

type String struct {
    // unexported fields
}

Implements: Value, Comparable

NewString

func NewString(v string) String

Key Methods

MethodSignatureDescription
Valuefunc (s String) Value() stringReturns the underlying Go string
Lengthfunc (s String) Length() intNumber of characters (rune count)
Containsfunc (s String) Contains(substr string) boolSubstring check
StartsWithfunc (s String) StartsWith(prefix string) boolPrefix check
EndsWithfunc (s String) EndsWith(suffix string) boolSuffix check
Upperfunc (s String) Upper() StringUppercase
Lowerfunc (s String) Lower() StringLowercase
IndexOffunc (s String) IndexOf(substr string) intFirst occurrence index (-1 if not found)
Substringfunc (s String) Substring(start, length int) StringExtract substring
Replacefunc (s String) Replace(old, replacement string) StringReplace all occurrences
ToCharsfunc (s String) ToChars() CollectionSplit into single-character strings
Comparefunc (s String) Compare(other Value) (int, error)Lexicographic comparison

Equivalence behavior: Equivalent() for strings is case-insensitive and normalizes whitespace (trims leading/trailing whitespace, collapses internal whitespace to single spaces).

Example:

s := types.NewString("Hello, World!")

fmt.Println(s.Length())                  // 13
fmt.Println(s.Contains("World"))         // true
fmt.Println(s.StartsWith("Hello"))       // true
fmt.Println(s.Upper())                   // HELLO, WORLD!
fmt.Println(s.Lower())                   // hello, world!
fmt.Println(s.IndexOf("World"))          // 7
fmt.Println(s.Substring(0, 5))           // Hello
fmt.Println(s.Replace("World", "Go"))    // Hello, Go!

// Equivalence is case-insensitive
a := types.NewString("  hello  world  ")
b := types.NewString("Hello World")
fmt.Println(a.Equivalent(b))             // true
fmt.Println(a.Equal(b))                  // false

Date

Represents a FHIRPath date value with variable precision (year, year-month, or year-month-day).

type Date struct {
    // unexported fields
}

Implements: Value, Comparable

Constructors

FunctionSignatureDescription
NewDatefunc NewDate(s string) (Date, error)Parses "2024", "2024-03", or "2024-03-15"
NewDateFromTimefunc NewDateFromTime(t time.Time) DateCreates from time.Time with day precision

Precision Constants

type DatePrecision int

const (
    YearPrecision  DatePrecision = iota // e.g., "2024"
    MonthPrecision                       // e.g., "2024-03"
    DayPrecision                         // e.g., "2024-03-15"
)

Key Methods

MethodSignatureDescription
Yearfunc (d Date) Year() intYear component
Monthfunc (d Date) Month() intMonth component (0 if not specified)
Dayfunc (d Date) Day() intDay component (0 if not specified)
Precisionfunc (d Date) Precision() DatePrecisionThe precision level
ToTimefunc (d Date) ToTime() time.TimeConvert to time.Time (defaults for missing components)
AddDurationfunc (d Date) AddDuration(value int, unit string) DateAdd a temporal duration
SubtractDurationfunc (d Date) SubtractDuration(value int, unit string) DateSubtract a temporal duration
Comparefunc (d Date) Compare(other Value) (int, error)Compare (may return error for ambiguous precision)

Supported duration units for AddDuration/SubtractDuration: "year", "years", "month", "months", "week", "weeks", "day", "days".

Example:

d, _ := types.NewDate("2024-03-15")
fmt.Println(d.Year())       // 2024
fmt.Println(d.Month())      // 3
fmt.Println(d.Day())        // 15
fmt.Println(d.Precision())  // DayPrecision

// Partial date
partial, _ := types.NewDate("2024-03")
fmt.Println(partial)          // 2024-03
fmt.Println(partial.Day())   // 0 (not specified)

// Date arithmetic
next := d.AddDuration(1, "month")
fmt.Println(next)            // 2024-04-15

DateTime

Represents a FHIRPath datetime value with variable precision from year to millisecond, with optional timezone.

type DateTime struct {
    // unexported fields
}

Implements: Value, Comparable

Constructors

FunctionSignatureDescription
NewDateTimefunc NewDateTime(s string) (DateTime, error)Parses ISO 8601 datetime strings
NewDateTimeFromTimefunc NewDateTimeFromTime(t time.Time) DateTimeCreates from time.Time with millisecond precision

Accepted formats include: "2024", "2024-03", "2024-03-15", "2024-03-15T10:30", "2024-03-15T10:30:00", "2024-03-15T10:30:00.000", "2024-03-15T10:30:00Z", "2024-03-15T10:30:00+05:00".

Precision Constants

type DateTimePrecision int

const (
    DTYearPrecision   DateTimePrecision = iota
    DTMonthPrecision
    DTDayPrecision
    DTHourPrecision
    DTMinutePrecision
    DTSecondPrecision
    DTMillisPrecision
)

Key Methods

MethodSignatureDescription
Yearfunc (dt DateTime) Year() intYear component
Monthfunc (dt DateTime) Month() intMonth component
Dayfunc (dt DateTime) Day() intDay component
Hourfunc (dt DateTime) Hour() intHour component
Minutefunc (dt DateTime) Minute() intMinute component
Secondfunc (dt DateTime) Second() intSecond component
Millisecondfunc (dt DateTime) Millisecond() intMillisecond component
ToTimefunc (dt DateTime) ToTime() time.TimeConvert to time.Time
AddDurationfunc (dt DateTime) AddDuration(value int, unit string) DateTimeAdd a temporal duration
SubtractDurationfunc (dt DateTime) SubtractDuration(value int, unit string) DateTimeSubtract a temporal duration
Comparefunc (dt DateTime) Compare(other Value) (int, error)Compare (may return error for ambiguous precision)

Supported duration units: "year", "years", "month", "months", "week", "weeks", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds", "millisecond", "milliseconds", "ms".

Example:

dt, _ := types.NewDateTime("2024-03-15T14:30:00Z")
fmt.Println(dt.Year())        // 2024
fmt.Println(dt.Hour())        // 14
fmt.Println(dt.Minute())      // 30
fmt.Println(dt)               // 2024-03-15T14:30:00Z

// DateTime arithmetic
later := dt.AddDuration(2, "hours")
fmt.Println(later)             // 2024-03-15T16:30:00Z

// From time.Time
now := types.NewDateTimeFromTime(time.Now())
fmt.Println(now.Type())        // DateTime

Time

Represents a FHIRPath time value with variable precision from hour to millisecond.

type Time struct {
    // unexported fields
}

Implements: Value, Comparable

Constructors

FunctionSignatureDescription
NewTimefunc NewTime(s string) (Time, error)Parses time strings like "14:30", "14:30:00", "T14:30:00.000"
NewTimeFromGoTimefunc NewTimeFromGoTime(t time.Time) TimeCreates from time.Time with millisecond precision

Precision Constants

type TimePrecision int

const (
    HourPrecision   TimePrecision = iota
    MinutePrecision
    SecondPrecision
    MillisPrecision
)

Key Methods

MethodSignatureDescription
Hourfunc (t Time) Hour() intHour component
Minutefunc (t Time) Minute() intMinute component
Secondfunc (t Time) Second() intSecond component
Millisecondfunc (t Time) Millisecond() intMillisecond component
Comparefunc (t Time) Compare(other Value) (int, error)Compare (may return error for ambiguous precision)

Example:

t, _ := types.NewTime("14:30:00")
fmt.Println(t.Hour())        // 14
fmt.Println(t.Minute())      // 30
fmt.Println(t.Second())      // 0
fmt.Println(t)               // 14:30:00

// With milliseconds
precise, _ := types.NewTime("T08:15:30.500")
fmt.Println(precise.Millisecond()) // 500

Quantity

Represents a FHIRPath quantity – a numeric value paired with a unit string. Supports UCUM unit normalization for comparing quantities with different but compatible units.

type Quantity struct {
    // unexported fields
}

Implements: Value, Comparable

Constructors

FunctionSignatureDescription
NewQuantityfunc NewQuantity(s string) (Quantity, error)Parses strings like "5.5 'mg'", "100 kg"
NewQuantityFromDecimalfunc NewQuantityFromDecimal(value decimal.Decimal, unit string) QuantityCreates from a decimal.Decimal and unit string

Key Methods

MethodSignatureDescription
Valuefunc (q Quantity) Value() decimal.DecimalReturns the numeric value
Unitfunc (q Quantity) Unit() stringReturns the unit string
Addfunc (q Quantity) Add(other Quantity) (Quantity, error)Add (same unit required)
Subtractfunc (q Quantity) Subtract(other Quantity) (Quantity, error)Subtract (same unit required)
Multiplyfunc (q Quantity) Multiply(factor decimal.Decimal) QuantityMultiply by a number
Dividefunc (q Quantity) Divide(divisor decimal.Decimal) (Quantity, error)Divide by a number
Normalizefunc (q Quantity) Normalize() ucum.NormalizedQuantityUCUM normalization
Comparefunc (q Quantity) Compare(other Value) (int, error)Compare (supports compatible units via UCUM)

Equivalence behavior: Equivalent() for quantities uses UCUM normalization, so 10 'cm' and 0.1 'm' are considered equivalent.

Example:

q, _ := types.NewQuantity("75.5 'kg'")
fmt.Println(q.Value()) // 75.5
fmt.Println(q.Unit())  // kg
fmt.Println(q)         // 75.5 kg

// Arithmetic
q2, _ := types.NewQuantity("2.5 'kg'")
sum, _ := q.Add(q2)
fmt.Println(sum)       // 78 kg

ObjectValue

Represents a FHIR® resource or complex type as a JSON object. This type is used internally to represent structured data within the evaluation engine. The Type() method attempts to infer the FHIR® type from the JSON structure (checking resourceType first, then structural patterns for common complex types).

type ObjectValue struct {
    // unexported fields
}

Implements: Value

NewObjectValue

func NewObjectValue(data []byte) *ObjectValue

Creates an ObjectValue from raw JSON bytes representing an object.

Key Methods

MethodSignatureDescription
Typefunc (o *ObjectValue) Type() stringInferred FHIR® type or "Object"
Datafunc (o *ObjectValue) Data() []byteRaw JSON bytes
Getfunc (o *ObjectValue) Get(field string) (Value, bool)Get a field value (cached)
GetCollectionfunc (o *ObjectValue) GetCollection(field string) CollectionGet a field as a Collection
Keysfunc (o *ObjectValue) Keys() []stringAll field names
Childrenfunc (o *ObjectValue) Children() CollectionAll child values
ToQuantityfunc (o *ObjectValue) ToQuantity() (Quantity, bool)Convert to Quantity if structure matches

Type inference: The Type() method recognizes FHIR® resource types (via resourceType field) and common complex types including Quantity, Coding, CodeableConcept, Reference, Period, Identifier, Range, Ratio, Attachment, HumanName, Address, ContactPoint, and Annotation.

Example:

data := []byte(`{"resourceType": "Patient", "id": "123", "active": true}`)
obj := types.NewObjectValue(data)

fmt.Println(obj.Type()) // Patient

if v, ok := obj.Get("id"); ok {
    fmt.Println(v) // 123
}

keys := obj.Keys()
fmt.Println(keys) // [resourceType id active]

TypeError

Represents a type mismatch error that can occur during operations on values.

type TypeError struct {
    Expected  string
    Actual    string
    Operation string
}

NewTypeError

func NewTypeError(expected, actual, operation string) *TypeError

Error

func (e *TypeError) Error() string
// Returns: "type error in <operation>: expected <expected>, got <actual>"

Example:

err := types.NewTypeError("Integer", "String", "comparison")
fmt.Println(err.Error()) // type error in comparison: expected Integer, got String

Utility Functions

JSONToCollection

Converts raw JSON bytes (which can be an object, array, or primitive) to a Collection.

func JSONToCollection(data []byte) (Collection, error)

Behavior:

  • JSON object: Returns a singleton collection with an *ObjectValue
  • JSON array: Returns a collection with one element per array item
  • JSON null: Returns an empty collection
  • JSON primitive: Returns a singleton collection with the corresponding type

Type Summary

TypeFHIRPath NameGo Backing TypeImplements
BooleanBooleanboolValue
IntegerIntegerint64Value, Comparable, Numeric
DecimalDecimaldecimal.DecimalValue, Comparable, Numeric
StringStringstringValue, Comparable
DateDateyear/month/day intsValue, Comparable
DateTimeDateTimecomponent ints + timezoneValue, Comparable
TimeTimehour/minute/second/millis intsValue, Comparable
QuantityQuantitydecimal.Decimal + unit stringValue, Comparable
*ObjectValue(inferred)[]byte JSONValue
Last updated on