Backed out 5 changesets (bug 1890092, bug 1888683) for causing build bustages & crash...
[gecko.git] / third_party / rust / uniffi_bindgen / src / bindings / python / templates / Helpers.py
blobdca962f176c34f6892dd21ea06a528f44a5d7f44
1 # A handful of classes and functions to support the generated data structures.
2 # This would be a good candidate for isolating in its own ffi-support lib.
4 class InternalError(Exception):
5 pass
7 class _UniffiRustCallStatus(ctypes.Structure):
8 """
9 Error runtime.
10 """
11 _fields_ = [
12 ("code", ctypes.c_int8),
13 ("error_buf", _UniffiRustBuffer),
16 # These match the values from the uniffi::rustcalls module
17 CALL_SUCCESS = 0
18 CALL_ERROR = 1
19 CALL_PANIC = 2
21 def __str__(self):
22 if self.code == _UniffiRustCallStatus.CALL_SUCCESS:
23 return "_UniffiRustCallStatus(CALL_SUCCESS)"
24 elif self.code == _UniffiRustCallStatus.CALL_ERROR:
25 return "_UniffiRustCallStatus(CALL_ERROR)"
26 elif self.code == _UniffiRustCallStatus.CALL_PANIC:
27 return "_UniffiRustCallStatus(CALL_PANIC)"
28 else:
29 return "_UniffiRustCallStatus(<invalid code>)"
31 def _rust_call(fn, *args):
32 # Call a rust function
33 return _rust_call_with_error(None, fn, *args)
35 def _rust_call_with_error(error_ffi_converter, fn, *args):
36 # Call a rust function and handle any errors
38 # This function is used for rust calls that return Result<> and therefore can set the CALL_ERROR status code.
39 # error_ffi_converter must be set to the _UniffiConverter for the error class that corresponds to the result.
40 call_status = _UniffiRustCallStatus(code=_UniffiRustCallStatus.CALL_SUCCESS, error_buf=_UniffiRustBuffer(0, 0, None))
42 args_with_error = args + (ctypes.byref(call_status),)
43 result = fn(*args_with_error)
44 _uniffi_check_call_status(error_ffi_converter, call_status)
45 return result
47 def _uniffi_check_call_status(error_ffi_converter, call_status):
48 if call_status.code == _UniffiRustCallStatus.CALL_SUCCESS:
49 pass
50 elif call_status.code == _UniffiRustCallStatus.CALL_ERROR:
51 if error_ffi_converter is None:
52 call_status.error_buf.free()
53 raise InternalError("_rust_call_with_error: CALL_ERROR, but error_ffi_converter is None")
54 else:
55 raise error_ffi_converter.lift(call_status.error_buf)
56 elif call_status.code == _UniffiRustCallStatus.CALL_PANIC:
57 # When the rust code sees a panic, it tries to construct a _UniffiRustBuffer
58 # with the message. But if that code panics, then it just sends back
59 # an empty buffer.
60 if call_status.error_buf.len > 0:
61 msg = _UniffiConverterString.lift(call_status.error_buf)
62 else:
63 msg = "Unknown rust panic"
64 raise InternalError(msg)
65 else:
66 raise InternalError("Invalid _UniffiRustCallStatus code: {}".format(
67 call_status.code))
69 # A function pointer for a callback as defined by UniFFI.
70 # Rust definition `fn(handle: u64, method: u32, args: _UniffiRustBuffer, buf_ptr: *mut _UniffiRustBuffer) -> int`
71 _UNIFFI_FOREIGN_CALLBACK_T = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_ulonglong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.POINTER(_UniffiRustBuffer))
73 # UniFFI future continuation
74 _UNIFFI_FUTURE_CONTINUATION_T = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_int8)