wit-bindgen-cli 0.61.1

CLI tool to generate bindings for WIT documents and the component model.
//@ [lang]
//@ path = 'gen/interface/test/moonbit-stream-write-cancel/controller/stub.mbt'
//@ pkg_config = """{ "supported-targets": "+wasm", "import": [{ "path": "test/moonbit-stream-write-cancel/async-core", "alias": "async-core" }, { "path": "test/moonbit-stream-write-cancel/interface/test/moonbit-stream-write-cancel/holder", "alias": "holder" }] }"""

///|
let never : (@async-core.Future[Unit], @async-core.Promise[Unit]) =
  @async-core.Future::new()

///|
let cancellation_seen : Ref[Bool] = { val: false }

///|
let cancellation_done : (@async-core.Future[Unit], @async-core.Promise[Unit]) =
  @async-core.Future::new()

///|
let second_write_seen : Ref[Bool] = { val: false }

///|
let peer_drop_producer_finished : Ref[Bool] = { val: false }

///|
let producer_done : (@async-core.Future[Unit], @async-core.Promise[Unit]) =
  @async-core.Future::new()

///|
pub async fn run_until_cancelled(
  background_group : @async-core.TaskGroup[Unit]
) -> Unit {
  let writer_started : (@async-core.Future[Unit], @async-core.Promise[Unit]) =
    @async-core.Future::new()
  let stream = @async-core.Stream::produce(async fn(sink) {
    // Return while a child owns a partially accepted write, forcing generated
    // finalization to wait for the child's canonical buffer cleanup.
    background_group.spawn_bg(async fn() {
      defer {
        cancellation_seen.val = true
        ignore(cancellation_done.1.complete(()))
      }
      @holder.mark_write_started()
      ignore(writer_started.1.complete(()))
      let data : FixedArray[@holder.Leaf] = [
        @holder.Leaf::leaf(),
        @holder.Leaf::leaf(),
      ]
      let _ = sink.write_all(data[:])
    })
    writer_started.0.get()
  }, cleanup=fn(value) { value.drop() })
  @holder.hold(stream)
  never.0.get()
}

///|
pub fn cancellation_observed() -> Bool {
  cancellation_seen.val
}

///|
pub async fn wait_cancellation_observed(
  _background_group : @async-core.TaskGroup[Unit]
) -> Unit {
  cancellation_done.0.get()
}

///|
pub async fn start_peer_drop(
  _background_group : @async-core.TaskGroup[Unit]
) -> Unit {
  let stream = @async-core.Stream::produce(async fn(sink) {
    defer {
      peer_drop_producer_finished.val = true
      ignore(producer_done.1.complete(()))
    }
    let first : FixedArray[@holder.Leaf] = [@holder.Leaf::leaf()]
    guard sink.write_all(first[:]) else { panic() }
    let second : FixedArray[@holder.Leaf] = [@holder.Leaf::leaf()]
    guard sink.write_all(second[:]) else { panic() }
    second_write_seen.val = true
    let third : FixedArray[@holder.Leaf] = [@holder.Leaf::leaf()]
    guard !sink.write_all(third[:]) else { panic() }
    let fourth : FixedArray[@holder.Leaf] = [@holder.Leaf::leaf()]
    guard !sink.write_all(fourth[:]) else { panic() }
  }, cleanup=fn(value) { value.drop() })
  guard stream.read(1) is Some(priming) && priming.length() == 1 else {
    panic()
  }
  priming[0].drop()
  @holder.hold(stream)
}

///|
pub fn second_write_started() -> Bool {
  second_write_seen.val
}

///|
pub fn producer_finished() -> Bool {
  peer_drop_producer_finished.val
}

///|
pub async fn wait_producer_finished(
  _background_group : @async-core.TaskGroup[Unit]
) -> Unit {
  producer_done.0.get()
}