(module main)

(fn maybe_value ((value i32)) -> (option i32)
  (some i32 value))

(fn maybe_empty () -> (option i32)
  (none i32))

(fn maybe_wide_value ((value i64)) -> (option i64)
  (some i64 value))

(fn maybe_wide_empty () -> (option i64)
  (none i64))

(fn maybe_float_value ((value f64)) -> (option f64)
  (some f64 value))

(fn maybe_float_empty () -> (option f64)
  (none f64))

(fn maybe_flag_value ((value bool)) -> (option bool)
  (some bool value))

(fn maybe_flag_empty () -> (option bool)
  (none bool))

(fn maybe_string_value ((value string)) -> (option string)
  (some string value))

(fn maybe_string_empty () -> (option string)
  (none string))

(fn result_ok_value ((value i32)) -> (result i32 i32)
  (ok i32 i32 value))

(fn result_err_value ((code i32)) -> (result i32 i32)
  (err i32 i32 code))

(fn option_value_or ((value (option i32)) (fallback i32)) -> i32
  (match value
    ((some payload)
      payload)
    ((none)
      fallback)))

(fn option_bump_or_zero ((value (option i32))) -> i32
  (match value
    ((some payload)
      (let bumped i32 (+ payload 1))
      bumped)
    ((none)
      0)))

(fn option_wide_value_or ((value (option i64)) (fallback i64)) -> i64
  (match value
    ((some payload)
      payload)
    ((none)
      fallback)))

(fn option_wide_bump_or_zero ((value (option i64))) -> i64
  (match value
    ((some payload)
      (let bumped i64 (+ payload 1i64))
      bumped)
    ((none)
      0i64)))

(fn option_float_value_or ((value (option f64)) (fallback f64)) -> f64
  (match value
    ((some payload)
      payload)
    ((none)
      fallback)))

(fn option_float_bump_or_zero ((value (option f64))) -> f64
  (match value
    ((some payload)
      (let bumped f64 (+ payload 1.0))
      bumped)
    ((none)
      0.0)))

(fn option_flag_value_or ((value (option bool)) (fallback bool)) -> bool
  (match value
    ((some payload)
      payload)
    ((none)
      fallback)))

(fn option_flag_selected_or ((value (option bool)) (fallback bool)) -> bool
  (match value
    ((some payload)
      (if payload
        true
        false)
      payload)
    ((none)
      fallback)))

(fn option_string_value_or ((value (option string)) (fallback string)) -> string
  (match value
    ((some payload)
      payload)
    ((none)
      fallback)))

(fn option_string_selected_or ((value (option string)) (fallback string)) -> string
  (match value
    ((some payload)
      (let chosen string payload)
      chosen)
    ((none)
      fallback)))

(fn result_value_or_code ((value (result i32 i32))) -> i32
  (match value
    ((ok payload)
      payload)
    ((err code)
      code)))

(fn result_score ((value (result i32 i32))) -> i32
  (match value
    ((ok payload)
      (+ payload 10))
    ((err code)
      code)))

(test "option match some payload"
  (= (option_value_or (maybe_value 42) 0) 42))

(test "option match none fallback"
  (= (option_value_or (maybe_empty) 7) 7))

(test "option match multi expression arm"
  (= (option_bump_or_zero (maybe_value 8)) 9))

(test "option i64 match some payload"
  (= (option_wide_value_or (maybe_wide_value 2147483648i64) 0i64) 2147483648i64))

(test "option i64 match none fallback"
  (= (option_wide_value_or (maybe_wide_empty) 7i64) 7i64))

(test "option i64 match multi expression arm"
  (= (option_wide_bump_or_zero (maybe_wide_value 8i64)) 9i64))

(test "option f64 match some payload"
  (= (option_float_value_or (maybe_float_value 42.5) 0.0) 42.5))

(test "option f64 match none fallback"
  (= (option_float_value_or (maybe_float_empty) 7.0) 7.0))

(test "option f64 match multi expression arm"
  (= (option_float_bump_or_zero (maybe_float_value 8.5)) 9.5))

(test "option bool match some payload"
  (option_flag_value_or (maybe_flag_value true) false))

(test "option bool match none fallback"
  (option_flag_value_or (maybe_flag_empty) true))

(test "option bool match multi expression arm"
  (option_flag_selected_or (maybe_flag_value true) false))

(test "option string match some payload"
  (= (option_string_value_or (maybe_string_value "slovo") "fallback") "slovo"))

(test "option string match none fallback"
  (= (option_string_value_or (maybe_string_empty) "fallback") "fallback"))

(test "option string match multi expression arm"
  (= (option_string_selected_or (maybe_string_value "oak") "fallback") "oak"))

(test "result match ok payload"
  (= (result_value_or_code (result_ok_value 30)) 30))

(test "result match err payload"
  (= (result_value_or_code (result_err_value 5)) 5))

(test "result match computed arm"
  (= (result_score (result_ok_value 2)) 12))

(fn main () -> i32
  0)
