rust-bindgen
rust-bindgen copied to clipboard
Emulate variadic methods using tuples
This PR introduces a new flag --tuple-varargs-len=<LEN> which can be used to emulate variadic methods using tuples of length up to <LEN>.
Example
If the generated function signature for a variadic method is:
extern "C" {
fn foo_bar(foo: &Foo, a: A, ...);
}
and the --tuple-varargs-len flag is set. A new method for the type Foo is introduced:
impl Foo {
unsafe fn bar(&self, a: A, varargs: impl VarArgs) {
varargs.call_foo_bar(self, a)
}
}
The user would use such method like this:
foo.bar(a, ()); // 0 variadic args
foo.bar(a, (10,)); // 1 variadic arg
foo.bar(a, (10, b"hello")); // 2 variadic args
foo.bar(a, (10, b"hello", false)); // 3 variadic args
...
To do this, the VarArgs trait is declared and implemented automatically up to the value of --tuple-varargs-len:
trait VarArgs {
unsafe fn call_foo_bar(self, foo: &Foo, a: A);
}
impl VarArgs for () {
unsafe fn call_foo_bar(self, foo: &Foo, a: A) {
let () = self;
foo_bar(foo, a)
}
}
impl<T0> VarArgs for (T0,) {
unsafe fn call_foo_bar(self, foo: &Foo, a: A) {
let (t0, ) = self;
foo_bar(foo, a, t0)
}
}
impl<T0, T1> VarArgs for (T0, T1) {
unsafe fn call_foo_bar(self, foo: &Foo, a: A) {
let (t0, t1) = self;
foo_bar(foo, a, t0, t1)
}
}
This has some disadvantages, such as the user not being able to just do foo.bar(a) or foo,bar(a, v) without getting somewhat confusing errors but this could be mitigated by properly documenting the VarArgs trait.
Fixes #407