forward
import forward from "forward";
struct Engine { sent: i64; }
fn Engine.send(*self, n: i64) { self.sent = self.sent + n; }
fn Engine.total(*const self) -> i64 { return self.sent; }
struct Client { engine: Engine; name: string; }
@tape { forward.gen_forward(Client, "engine"); }
var c: Client = Client { engine: Engine { sent: 0; }; name: "a"; };
c.send(3);
let t = c.total(); // 3: Client.total calls c.engine.total()forward writes forwarding methods for you. A type that holds another in
a field, such as a facade over an engine or a wrapper that adds a field or
two, gets one method for each method of the inner type that takes a
receiver, with the same name and parameters, calling it on the field. When
the inner type gains a method, the wrapper has it too.
gen_forward
pub @tape fn gen_forward(T: type, field: []const u8, names: []const []const u8 = [],
visible: bool = false)For each method m of the type of T’s field field:
m(*self, ...)becomesfn T.m(*self, ...)callingself.field.m(...);m(self, ...)andm(*const self, ...)becomefn T.m(*const self, ...);- the result is
m’s: nothing, a value, orT or E.
A method without a receiver (fn Engine.new()) is not forwarded, and
neither is one T already has: write a method yourself and it wins.
names, when not empty, chooses which methods are forwarded:
@tape { forward.gen_forward(Client, "engine", ["send"]); } // only sendThe methods are private to your module; visible: true makes them pub,
for a module that exports the wrapper (its types must be pub then too).
It reads the inner type’s methods with @typeof(T).methods
(reflection), so
it is also an example of a generator that writes one declaration per
member of a type.
Last modified: