(module main)

(enum Reading
  Missing
  (Value i32)
  (Offset i32))

(fn missing () -> Reading
  (Reading.Missing))

(fn value ((payload i32)) -> Reading
  (Reading.Value payload))

(fn echo ((reading Reading)) -> Reading
  reading)

(fn local_reading ((payload i32)) -> Reading
  (let reading Reading (Reading.Value payload))
  reading)

(fn same_reading ((left Reading) (right Reading)) -> bool
  (= left right))

(fn reading_code ((reading Reading)) -> i32
  (match reading
    ((Reading.Missing)
      0)
    ((Reading.Value payload)
      payload)
    ((Reading.Offset payload)
      (+ payload 100))))

(fn call_flow ((payload i32)) -> Reading
  (echo (local_reading payload)))

(test "enum payload constructor equality"
  (= (Reading.Value 7) (value 7)))

(test "enum payload equality compares payload"
  (if (= (Reading.Value 7) (Reading.Value 8))
    false
    true))

(test "enum payloadless equality"
  (= (Reading.Missing) (missing)))

(test "enum payload local return call flow"
  (= (call_flow 9) (Reading.Value 9)))

(test "enum payload parameter equality"
  (same_reading (value 11) (Reading.Value 11)))

(test "enum payload match missing"
  (= (reading_code (Reading.Missing)) 0))

(test "enum payload match value"
  (= (reading_code (Reading.Value 12)) 12))

(test "enum payload match offset"
  (= (reading_code (Reading.Offset 5)) 105))

(fn main () -> i32
  (reading_code (call_flow 42)))
