Mapping for Interfaces
Interfaces in IDL map to traits in Rust.
Parameter Passing
The parameter direction (in, inout, out) determines how parameters are
passed in the generated Rust code.
in Parameters
For in parameters, the passing convention depends on the type:
| Type Category | Rust Passing Convention | Example |
|---|---|---|
Primitives (bool, integers, char, f32, f64) | By value | value: i32 |
| Enums | By value | value: MyEnum |
| Bitmasks | By value | value: MyBitmask |
| Strings | Immutable slice reference | value: &str |
| Sequences | Immutable slice reference | value: &[T] |
| Structs, Unions, Exceptions | Immutable reference | value: &MyStruct |
| Interfaces | Boxed trait object | value: Box<dyn MyInterface> |
inout and out Parameters
Both inout and out parameters are passed as mutable references:
#![allow(unused)]
fn main() {
fn operation(&mut self, value: &mut i32);
}
Self Parameter
The self parameter depends on the function’s annotations:
| Annotation | Self Parameter |
|---|---|
| (none) | &mut self |
@const | &self |
@static | (no self parameter) |
Static functions require a where Self: Sized bound since they cannot be
called through trait objects.
Exception Handling
Exceptions in IDL are mapped to Rust’s Result type:
| Exception Count | Return Type |
|---|---|
| 0 | T (or () for void) |
| 1 | ExceptionNameResult<T> (type alias for Result<T, ExceptionName>) |
| 2+ | Result<T, Box<dyn Error>> |
Nested Types
Type definitions or aliases defined inside IDL interfaces will be defined in the outer scope, prefixed with the name of the interface.
Example
// IDL
interface MyInterface {
boolean negate(boolean value);
void increment(inout long value);
@static
float square_root(in float value);
@const
void print(Nested value) raises (MyException);
int32 throws_multiple() raises(MyException, MyOtherException);
struct Nested {};
};
#![allow(unused)]
fn main() {
// Rust
pub trait MyInterface {
fn negate(&mut self, value: bool) -> bool;
fn increment(&mut self, value: &mut i32);
fn square_root(value: f32) -> f32
where
Self: Sized;
fn print(&self, value: &Nested) -> MyExceptionResult<()>;
fn throws_multiple(&mut self) -> Result<i32, Box<dyn Error>>;
}
pub struct MyInterfaceNested {}
}
Inheritance
Derived interfaces become additional trait bounds in Rust.
// IDL
interface CordA {};
interface CordB {};
interface CordC {};
interface Vector3 : CordA, CordB, CordC {};
#![allow(unused)]
fn main() {
// Rust
trait CordA {}
trait CordB {}
trait CordC {}
trait Vector3 : CordA + CordB + CordC {}
}
Note that the above means that any type that implements the Vector3 trait
must manually implement CordA, CordB, and CordC.