(module main)

(import std.string (len concat byte_at_result slice_result starts_with ends_with contains index_of_option last_index_of_option trim_ascii_start trim_ascii_end trim_ascii parse_i32_result parse_i32_option parse_u32_result parse_u32_option parse_i64_result parse_i64_option parse_u64_result parse_u64_option parse_f64_result parse_f64_option parse_bool_result parse_bool_option parse_i32_or_zero parse_u32_or_zero parse_i64_or_zero parse_u64_or_zero parse_f64_or_zero parse_bool_or_false parse_i32_or parse_u32_or parse_i64_or parse_u64_or parse_f64_or parse_bool_or))

(fn imported_string_concat () -> string
  (concat "slo" "vo"))

(fn imported_string_len_concat_score () -> i32
  (+ (len (imported_string_concat)) 37))

(fn imported_string_byte_at_ok () -> bool
  (if (= (unwrap_ok (byte_at_result "slovo" 0)) 115)
    (if (= (unwrap_ok (byte_at_result "slovo" 3)) 118)
      (if (= (unwrap_err (byte_at_result "slovo" -1)) 1)
        (= (unwrap_err (byte_at_result "slovo" 5)) 1)
        false)
      false)
    false))

(fn imported_string_slice_ok () -> bool
  (if (= (unwrap_ok (slice_result "slovo" 1 3)) "lov")
    (if (= (unwrap_ok (slice_result "slovo" 0 5)) "slovo")
      (= (unwrap_err (slice_result "slovo" 4 2)) 1)
      false)
    false))

(fn imported_string_boundaries_ok () -> bool
  (if (starts_with "slovo" "slo")
    (if (starts_with "slovo" "")
      (if (starts_with "slovo" "ovo")
        false
        (if (ends_with "slovo" "ovo")
          (if (ends_with "slovo" "")
            (if (ends_with "slovo" "slo")
              false
              true)
            false)
          false))
      false)
    false))

(fn imported_string_parse_result_ok () -> bool
  (if (= (unwrap_ok (parse_i32_result "40")) 40)
    (if (= (unwrap_ok (parse_u32_result "40")) 40u32)
      (if (= (unwrap_ok (parse_i64_result "40")) 40i64)
        (if (= (unwrap_ok (parse_u64_result "40")) 40u64)
          (if (= (unwrap_ok (parse_f64_result "40.0")) 40.0)
            (imported_string_parse_bool_ok)
            false)
          false)
        false)
      false)
    false))

(fn imported_string_parse_bool_ok () -> bool
  (if (unwrap_ok (parse_bool_result "true"))
    (= (unwrap_err (parse_bool_result "TRUE")) 1)
    false))

(fn imported_string_parse_options_ok () -> bool
  (if (match (parse_i32_option "40")
    ((some payload)
      (= payload 40))
    ((none)
      false))
    (if (match (parse_i32_option "bad")
      ((some payload)
        false)
      ((none)
        true))
      (if (match (parse_u32_option "40")
        ((some payload)
          (= payload 40u32))
        ((none)
          false))
        (if (match (parse_u32_option "bad")
          ((some payload)
            false)
          ((none)
            true))
          (if (match (parse_i64_option "40")
            ((some payload)
              (= payload 40i64))
            ((none)
              false))
            (if (match (parse_i64_option "bad")
              ((some payload)
                false)
              ((none)
                true))
              (if (match (parse_u64_option "40")
                ((some payload)
                  (= payload 40u64))
                ((none)
                  false))
                (if (match (parse_u64_option "bad")
                  ((some payload)
                    false)
                  ((none)
                    true))
                  (if (match (parse_f64_option "40.0")
                    ((some payload)
                      (= payload 40.0))
                    ((none)
                      false))
                    (if (match (parse_f64_option "bad")
                      ((some payload)
                        false)
                      ((none)
                        true))
                      (if (match (parse_bool_option "true")
                        ((some payload)
                          payload)
                        ((none)
                          false))
                        (match (parse_bool_option "bad")
                          ((some payload)
                            false)
                          ((none)
                            true))
                        false)
                      false)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_string_parse_integer_fallbacks_ok () -> bool
  (if (= (parse_i32_or_zero "40") 40)
    (if (= (parse_i32_or_zero "bad") 0)
      (if (= (parse_u32_or_zero "40") 40u32)
        (if (= (parse_u32_or_zero "bad") 0u32)
          (if (= (parse_i64_or_zero "40") 40i64)
            (if (= (parse_i64_or_zero "bad") 0i64)
              (if (= (parse_u64_or_zero "40") 40u64)
                (= (parse_u64_or_zero "bad") 0u64)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_string_parse_float_bool_fallbacks_ok () -> bool
  (if (= (parse_f64_or_zero "40.0") 40.0)
    (if (= (parse_f64_or_zero "bad") 0.0)
      (if (parse_bool_or_false "true")
        (if (parse_bool_or_false "bad")
          false
          (if (parse_bool_or_false "false")
            false
            true))
        false)
      false)
    false))

(fn imported_string_parse_custom_fallbacks_ok () -> bool
  (if (= (parse_i32_or "40" 7) 40)
    (if (= (parse_i32_or "bad" 7) 7)
      (if (= (parse_u32_or "40" 9u32) 40u32)
        (if (= (parse_u32_or "bad" 9u32) 9u32)
          (if (= (parse_i64_or "40" 9i64) 40i64)
            (if (= (parse_i64_or "bad" 9i64) 9i64)
              (if (= (parse_u64_or "40" 11u64) 40u64)
                (if (= (parse_u64_or "bad" 11u64) 11u64)
                  (if (= (parse_f64_or "40.0" 1.5) 40.0)
                    (if (= (parse_f64_or "bad" 1.5) 1.5)
                      (if (parse_bool_or "true" false)
                        (if (parse_bool_or "bad" true)
                          true
                          false)
                        false)
                      false)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_option_i32_is_some_value ((actual (option i32)) (expected i32)) -> bool
  (match actual
    ((some payload)
      (= payload expected))
    ((none)
      false)))

(fn imported_option_i32_is_none ((actual (option i32))) -> bool
  (match actual
    ((some payload)
      false)
    ((none)
      true)))

(fn imported_string_search_ok () -> bool
  (if (contains "alpha beta alpha" "beta")
    (if (contains "alpha" "z")
      false
      (if (contains "alpha" "")
        (if (imported_option_i32_is_some_value (index_of_option "alpha beta alpha" "alpha") 0)
          (if (imported_option_i32_is_none (index_of_option "alpha" "z"))
            (if (imported_option_i32_is_some_value (index_of_option "alpha" "") 0)
              (if (imported_option_i32_is_some_value (last_index_of_option "alpha beta alpha" "alpha") 11)
                (if (imported_option_i32_is_some_value (last_index_of_option "alpha" "") 5)
                  (imported_option_i32_is_none (last_index_of_option "alpha" "z"))
                  false)
                false)
              false)
            false)
          false)
        false))
    false))

(fn imported_string_ascii_trim_ok () -> bool
  (if (= (trim_ascii_start " \t\nslovo") "slovo")
    (if (= (trim_ascii_end "slovo \t\n") "slovo")
      (if (= (trim_ascii " \t\nslovo \t\n") "slovo")
        (if (= (trim_ascii " \t\n") "")
          (= (trim_ascii "slovo") "slovo")
          false)
        false)
      false)
    false))

(fn imported_string_helpers_ok () -> bool
  (if (= (imported_string_len_concat_score) 42)
    (if (imported_string_byte_at_ok)
      (if (imported_string_slice_ok)
        (if (imported_string_boundaries_ok)
          (if (imported_string_parse_result_ok)
            (if (imported_string_parse_options_ok)
              (if (imported_string_parse_integer_fallbacks_ok)
                (if (imported_string_parse_float_bool_fallbacks_ok)
                  (if (imported_string_parse_custom_fallbacks_ok)
                    (if (imported_string_search_ok)
                      (imported_string_ascii_trim_ok)
                      false)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn main () -> i32
  (if (imported_string_helpers_ok)
    42
    1))

(test "explicit std string len concat"
  (= (imported_string_len_concat_score) 42))

(test "explicit std string byte_at_result wrapper"
  (imported_string_byte_at_ok))

(test "explicit std string slice_result wrapper"
  (imported_string_slice_ok))

(test "explicit std string boundary wrappers"
  (imported_string_boundaries_ok))

(test "explicit std string parse result wrappers"
  (imported_string_parse_result_ok))

(test "explicit std string parse option wrappers"
  (imported_string_parse_options_ok))

(test "explicit std string parse integer fallbacks"
  (imported_string_parse_integer_fallbacks_ok))

(test "explicit std string parse float bool fallbacks"
  (imported_string_parse_float_bool_fallbacks_ok))

(test "explicit std string parse custom fallbacks"
  (imported_string_parse_custom_fallbacks_ok))

(test "explicit std string search helpers"
  (imported_string_search_ok))

(test "explicit std string ascii trim helpers"
  (imported_string_ascii_trim_ok))

(test "explicit std string helpers all"
  (= (main) 42))
