moonbit中如何发起http

moonbit中如何发起http调用, 比如, 调用js中的fetch, 或者类似的axios

需要通过 FFI 方式调用 JavaScript 去请求.

Gemini 生成的代码, 细节没有完全验证… 参考一下

type JsValue // 假设已定义,代表 JavaScript 值

// 代表 fetch 函数的 Response 对象
type JsResponse

pub extern "js" fn fetch_ffi(url: String) -> JsValue =
  #|url => fetch(url)

pub extern "js" fn JsResponse::json_ffi(self: JsValue) -> JsValue =
  #|response => response.json()

pub extern "js" fn JsResponse::text_ffi(self: JsValue) -> JsValue =
  #|response => response.text()

// 为了简化示例,我们假设 then 方法直接传入一个处理函数
pub extern "js" fn JsValue::then_ffi(self: JsValue, callback: (JsValue) -> JsValue) -> JsValue =
  #| (promise, callback) => promise.then(callback) 

// 辅助函数,将 MoonBit 字符串转换为 JsValue
pub extern "js" fn string_to_js_value_ffi(str : String) -> JsValue =
  #|str => str

// 辅助函数, 将JsValue 转换为 MoonBit 字符串
pub extern "js" fn js_value_to_string_ffi(str : JsValue) -> String =
   #|str => str

/// 发起 fetch 请求
///
/// # Arguments
///
/// * `url` - 请求的 URL
///
/// # Returns
///
/// 返回一个 Promise (JsValue),可以使用 `then` 方法处理结果
pub fn fetch(url: String) -> JsValue {
  fetch_ffi(url)
}

// then 方法,用于处理 Promise 的结果
pub fn then(promise: JsValue, callback: (JsResponse) -> JsValue) -> JsValue {
  promise.then_ffi(fn (js_value: JsValue) {
    callback(JsResponse(js_value)) // 将 JsValue 包装成 JsResponse
  })
}

// 从 JsResponse 中获取 JSON 数据 (返回一个 Promise)
pub fn json(response: JsResponse) -> JsValue {
  response.0.json_ffi()
}

// 从 JsResponse 中获取文本数据 (返回一个 Promise)
pub fn text(response: JsResponse) -> JsValue{
  response.0.text_ffi()
}

// 将Moonbit String 转换成 JsValue
pub fn to_js_value(str : String) -> JsValue {
  string_to_js_value_ffi(str)
}

// 将JsValue 转换成 Moonbit String
pub fn from_js_value(str : JsValue) -> String {
  js_value_to_string_ffi(str)
}

// 用于表示 JsResponse 的结构体
pub struct JsResponse(JsValue)

//使用例子
//pub fn main {
//   let promise = fetch(to_js_value("https://api.example.com/data"))
//   let _ = promise.then_ffi(fn (response: JsValue) {
//      let data = response.json()
//       data.then_ffi(fn(j : JsValue) {
//         debug(from_js_value(j))
//       })      
//   })  
//}
//
//
//test {
//  let promise = fetch(to_js_value("https://www.baidu.com"))
//  let _ = then(promise, fn (response: JsResponse) {
//    let data = text(response)
//    let _ = then(data, fn(j : JsResponse) {
//        debug(from_js_value(j.0))
//    })
//  })
//  
//  
//}