wrap-cli icon indicating copy to clipboard operation
wrap-cli copied to clipboard

Bug: Support interface invocations in Rust

Open krisbitney opened this issue 3 years ago • 0 comments

In AssemblyScript wrappers, we can get an interface's registered implementation URIs and use one of the URIs to instantiate an interface module. This makes it possible for us to invoke an interface agnostic to its implementation.

The logic in the AssemblyScript and Rust bindings is different. In Rust, it is not possible to invoke an interface because we are generating interface modules as though they were standard modules. The Rust method attempts to invoke the interface URI rather than the URI of an implementation.

For example, contrast the following generated code for Rust and AssemblyScript using the same schema:

Schema

#import { Module } into Interface from "wrap://ens/goerli/interface.sleep.wrappers.eth"
#use { getImplementations } for Interface

Rust Codegen

pub struct SleepInterfaceModule {}

impl SleepInterfaceModule {
    pub const URI: &'static str = "wrap://ens/goerli/interface.sleep.wrappers.eth";

    pub fn new() -> SleepInterfaceModule {
        SleepInterfaceModule {}
    }

    pub fn sleep(args: &ArgsSleep) -> Result<Option<bool>, String> {
        let uri = SleepInterfaceModule::URI;
        let args = serialize_sleep_args(args).map_err(|e| e.to_string())?;
        let result = subinvoke::wrap_subinvoke(
            uri,
            "sleep",
            args,
        )?;
        deserialize_sleep_result(result.as_slice()).map_err(|e| e.to_string())
    }
}

AssemblyScript Codegen

export class SleepInterface_Module {

  public static interfaceUri: string = "wrap://ens/goerli/interface.sleep.wrappers.eth";

  public uri: string;

  constructor(uri: string) {
    this.uri = uri;
  }

  public sleep(
    args: Args_sleep
  ): Result<Option<bool>, string> {
    const argsBuf = serializesleepArgs(args);
    const result = wrap_subinvokeImplementation(
      "wrap://ens/goerli/interface.sleep.wrappers.eth",
      this.uri,
      "sleep",
      argsBuf
    );

    if (result.isErr) {
      return Result.Err<Option<bool>, string>(
        result.unwrapErr()
      );
    }

    return Result.Ok<Option<bool>, string>(
      deserializesleepResult(result.unwrap())
    );
  }
}

krisbitney avatar Aug 11 '22 13:08 krisbitney