pub struct MultiBindings { /* private fields */ }
Expand description

Output of the MultiAbigen build process. MultiBindings wraps a group of built contract bindings that have yet to be written to disk.

MultiBindings enables the user to

  1. Write a collection of bindings to a rust module
  2. Write a collection of bindings to a rust lib
  3. Ensure that a collection of bindings matches an on-disk module or lib.

Generally we recommend writing the bindings to a module folder within your rust project. Users seeking to create “official” bindings for some project may instead write an entire library to publish via crates.io.

Rather than using MultiAbigen in a build script, we recommend committing the generated files, and replacing the build script with an integration test. To enable this, we have provided MultiBindings::ensure_consistent_bindings and MultiBindings::ensure_consistent_crate. These functions generate the expected module or library in memory, and check that the on-disk files match the expected files. We recommend running these inside CI.

This has several advantages:

  • No need for downstream users to compile the build script
  • No need for downstream users to run the whole abigen! generation steps
  • The generated code is more usable in an IDE
  • CI will fail if the generated code is out of date (if abigen! or the contract’s ABI itself changed)

Implementations§

Returns the number of contracts to generate bindings for.

Returns whether there are any bindings to be generated

Generates all the bindings and writes them to the given module

Example

Read all json abi files from the ./abi directory

abi
├── ERC20.json
├── Contract1.json
├── Contract2.json
...

and write them to the ./src/contracts location as

src/contracts
├── mod.rs
├── er20.rs
├── contract1.rs
├── contract2.rs
...
let gen = MultiAbigen::from_json_files("./abi").unwrap();
let bindings = gen.build().unwrap();
bindings.write_to_module("./src/contracts", false).unwrap();

Generates all the bindings and writes a library crate containing them to the provided path

Example

Read all json abi files from the ./abi directory

abi
├── ERC20.json
├── Contract1.json
├── Contract2.json
├── Contract3/
    ├── Contract3.json
...

and write them to the ./bindings location as

bindings
├── Cargo.toml
├── src/
    ├── lib.rs
    ├── er20.rs
    ├── contract1.rs
    ├── contract2.rs
...
let gen = MultiAbigen::from_json_files("./abi").unwrap();
let bindings = gen.build().unwrap();
bindings.write_to_crate(
    "my-crate", "0.0.5", "./bindings", false
).unwrap();

This ensures that the already generated bindings crate matches the output of a fresh new run. Run this in a rust test, to get notified in CI if the newly generated bindings deviate from the already generated ones, and it’s time to generate them again. This could happen if the ABI of a contract or the output that ethers generates changed.

If this functions is run within a test during CI and fails, then it’s time to update all bindings.

Returns

Ok(()) if the freshly generated bindings match with the existing bindings. Otherwise an Err(_) containing an eyre::Report with more information.

Example

Check that the generated files are up to date

#[test]
fn generated_bindings_are_fresh() {
 let project_root = std::path::Path::new(&env!("CARGO_MANIFEST_DIR"));
 let abi_dir = project_root.join("abi");
 let gen = MultiAbigen::from_json_files(&abi_dir).unwrap();
 let bindings = gen.build().unwrap();
 bindings.ensure_consistent_crate(
    "my-crate", "0.0.1", project_root.join("src/contracts"), false, true
 ).expect("inconsistent bindings");
}

This ensures that the already generated bindings module matches the output of a fresh new run. Run this in a rust test, to get notified in CI if the newly generated bindings deviate from the already generated ones, and it’s time to generate them again. This could happen if the ABI of a contract or the output that ethers generates changed.

If this functions is run within a test during CI and fails, then it’s time to update all bindings.

Returns

Ok(()) if the freshly generated bindings match with the existing bindings. Otherwise an Err(_) containing an eyre::Report with more information.

Example

Check that the generated files are up to date

#[test]
fn generated_bindings_are_fresh() {
 let project_root = std::path::Path::new(&env!("CARGO_MANIFEST_DIR"));
 let abi_dir = project_root.join("abi");
 let gen = MultiAbigen::from_json_files(&abi_dir).unwrap();
 let bindings = gen.build().unwrap();
 bindings.ensure_consistent_module(
    project_root.join("src/contracts"), false
 ).expect("inconsistent bindings");
}

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more