(module main)

(fn narrow ((value i64)) -> (result i32 i32)
  (std.num.i64_to_i32_result value))

(fn low_ok () -> (result i32 i32)
  (narrow -2147483648i64))

(fn high_ok () -> (result i32 i32)
  (narrow 2147483647i64))

(fn negative_ok () -> (result i32 i32)
  (narrow -7i64))

(fn below_low_err () -> (result i32 i32)
  (narrow -2147483649i64))

(fn above_high_err () -> (result i32 i32)
  (narrow 2147483648i64))

(test "i64 low bound narrows to i32"
  (let value (result i32 i32) (low_ok))
  (if (std.result.is_ok value)
    (= (std.result.unwrap_ok value) -2147483648)
    false))

(test "i64 high bound narrows to i32"
  (let value (result i32 i32) (high_ok))
  (if (std.result.is_ok value)
    (= (std.result.unwrap_ok value) 2147483647)
    false))

(test "negative i64 narrows to i32"
  (let value (result i32 i32) (negative_ok))
  (if (std.result.is_ok value)
    (= (std.result.unwrap_ok value) -7)
    false))

(test "below i32 range returns err"
  (let value (result i32 i32) (below_low_err))
  (if (std.result.is_err value)
    (= (std.result.unwrap_err value) 1)
    false))

(test "above i32 range returns err"
  (let value (result i32 i32) (above_high_err))
  (if (std.result.is_err value)
    (= (std.result.unwrap_err value) 1)
    false))

(fn main () -> i32
  (let value (result i32 i32) (negative_ok))
  (if (std.result.is_ok value)
    (if (= (std.result.unwrap_ok value) -7)
      0
      1)
    (std.result.unwrap_err value)))
