rusttuplesdeserialization

How to deserialize multiple values of the same type from ethers call without listing all in a tuple?


I am working with some API that returns bytes that I can deserialize by defining their types.

result: (f64, f64, f64) = api.call();

Can I do the same by dynamically by passing a value n for the number of elements?

All elements of the tuple are of the same type. I would like to do something like this:

result: tuple(f64, 3) = api.call();

Here is the API of the call function.

Edit: In case anyone ever encounters that issue in the future. I could deserialize the output by adopting this solution.


Solution

  • For reference: call() returns a Result<D: Detokenize, _>. Detokenize is mainly implemented for all T that implement Tokenizable.

    All types that can receive the result are listed here.

    Note that additional to tuples of various size, it's also implemented for:

    impl<T: TokenizableItem + Clone, const N: usize> Tokenizable for [T; N]
    

    Further, note that it is an async function with a Result, meaning you have to await it and deal with the potential error.

    So you should(tm) be able to write:

    result: [f64; 3] = api.call().await.unwrap();
    

    Of course in a real project I would advise to replace unwrap() with some proper error handling.

    Disclaimer: I don't know how to use the rest of ethers-core, so I'm unable to verify this in a test project. This information is purely derived from the documentation.


    Static vs dynamic size

    [f64; 3] requires you to know the number of elements at compile time.

    Note that another Tokenizable is Vec<T>, meaning you could also specify Vec<T> as a result type. The length of this one will then be resolved at runtime, depending on how many elements of T the api.call() returns.


    Further background information

    Note that there is no such thing as a tuple that has N number of T elements, because a tuple is not a repetition of one type, it's a collection of types. Every element of a tuple can have a different type.

    If you want to represent a repetition of one type, an array is what you really want. It's defined as one type T repeated N times: [T; N].