summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift')
-rw-r--r--third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift69
1 files changed, 69 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift b/third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift
new file mode 100644
index 0000000000..167e4c7546
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/bindings/swift/templates/ForeignExecutorTemplate.swift
@@ -0,0 +1,69 @@
+private let UNIFFI_RUST_TASK_CALLBACK_SUCCESS: Int8 = 0
+private let UNIFFI_RUST_TASK_CALLBACK_CANCELLED: Int8 = 1
+private let UNIFFI_FOREIGN_EXECUTOR_CALLBACK_SUCCESS: Int8 = 0
+private let UNIFFI_FOREIGN_EXECUTOR_CALLBACK_CANCELED: Int8 = 1
+private let UNIFFI_FOREIGN_EXECUTOR_CALLBACK_ERROR: Int8 = 2
+
+// Encapsulates an executor that can run Rust tasks
+//
+// On Swift, `Task.detached` can handle this we just need to know what priority to send it.
+public struct UniFfiForeignExecutor {
+ var priority: TaskPriority
+
+ public init(priority: TaskPriority) {
+ self.priority = priority
+ }
+
+ public init() {
+ self.priority = Task.currentPriority
+ }
+}
+
+fileprivate struct FfiConverterForeignExecutor: FfiConverter {
+ typealias SwiftType = UniFfiForeignExecutor
+ // Rust uses a pointer to represent the FfiConverterForeignExecutor, but we only need a u8.
+ // let's use `Int`, which is equivalent to `size_t`
+ typealias FfiType = Int
+
+ public static func lift(_ value: FfiType) throws -> SwiftType {
+ UniFfiForeignExecutor(priority: TaskPriority(rawValue: numericCast(value)))
+ }
+ public static func lower(_ value: SwiftType) -> FfiType {
+ numericCast(value.priority.rawValue)
+ }
+
+ public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
+ fatalError("FfiConverterForeignExecutor.read not implemented yet")
+ }
+ public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
+ fatalError("FfiConverterForeignExecutor.read not implemented yet")
+ }
+}
+
+
+fileprivate func uniffiForeignExecutorCallback(executorHandle: Int, delayMs: UInt32, rustTask: UniFfiRustTaskCallback?, taskData: UnsafeRawPointer?) -> Int8 {
+ if let rustTask = rustTask {
+ let executor = try! FfiConverterForeignExecutor.lift(executorHandle)
+ Task.detached(priority: executor.priority) {
+ if delayMs != 0 {
+ let nanoseconds: UInt64 = numericCast(delayMs * 1000000)
+ try! await Task.sleep(nanoseconds: nanoseconds)
+ }
+ rustTask(taskData, UNIFFI_RUST_TASK_CALLBACK_SUCCESS)
+ }
+ return UNIFFI_FOREIGN_EXECUTOR_CALLBACK_SUCCESS
+ } else {
+ // When rustTask is null, we should drop the foreign executor.
+ // However, since its just a value type, we don't need to do anything here.
+ return UNIFFI_FOREIGN_EXECUTOR_CALLBACK_SUCCESS
+ }
+}
+
+fileprivate func uniffiInitForeignExecutor() {
+ {%- match ci.ffi_foreign_executor_callback_set() %}
+ {%- when Some with (fn) %}
+ {{ fn.name() }}(uniffiForeignExecutorCallback)
+ {%- when None %}
+ {#- No foreign executor, we don't set anything #}
+ {% endmatch %}
+}