(module main)

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

(fn zero_ok () -> (result i64 i32)
  (narrow (- 2.5 2.5)))

(fn negative_ok () -> (result i64 i32)
  (narrow (- 1.0 13.0)))

(fn fractional_err () -> (result i64 i32)
  (narrow (/ 7.0 2.0)))

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

(test "f64 zero narrows to i64"
  (let value (result i64 i32) (zero_ok))
  (if (std.result.is_ok value)
    (= (std.result.unwrap_ok value) 0i64)
    false))

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

(test "fractional f64 returns err for i64"
  (let value (result i64 i32) (fractional_err))
  (if (std.result.is_err value)
    (= (std.result.unwrap_err value) 1)
    false))

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

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