#Error while assigning a variable based on condition

1 messages · Page 1 of 1 (latest)

bright orbit
#

https://github.com/golota60/idas-bug here's a simple minimal reproduction of the issue. The error is on line 6-9, where the types always seem to be incompatible, no matter what I do

I'm using an external library to connect to a desk. Based on a condition, i want the "desk getter" function to either be get_instance or get_instance_by_mac cause I might have a MAC address or I might not. The errors jump between "incompatible types" to the fact that the compiler cannot know the size of a value upfront, so posting an exact error would be hard, cause applying one fix introduces a different error :/

The problem arises when i want to assign the result of one of these functions to a variable. I've tried Boxing them, converting to Closures and much more over the past few days, and at this point I am kinda helpless. Googling the errors points me to stuff that seem to have little relevance to my exact problem.

If someone could tell me how I can achieve this behavior and explain what is happening to me like I'm 5, I would be really grateful. Thanks in advance 🙂

GitHub

Contribute to golota60/idas-bug development by creating an account on GitHub.

#

Error while assigning a variable based on condition

bright orbit
#

bump ferrisPlead

frosty siren
#

Yuck. I don't know a way you can solve it while still using those two functions—the problem is that they return something, and they could return two different somethings, so you can't assign them to the same variable. The library should probably either return an Enum or Box the dynamnic response and have a trait object but... you can't fix that without forking.

However, if you look at the implementation of get_instance_by_mac you can basically copy it and instead of passing Some(addr) to get_desks, you pass maybe_mac_address.map(BDAddr::parse) (or whatever the actual correct code is for what they're doing there.

bright orbit
#

thank you! will try that

gritty ember
# bright orbit thank you! will try that

you don't actually need to go that far and change how a library is implemented, generally speaking. You can use Either from the either crate (or copy it and its Future implementation, it's maybe 30 lines):

    let desk_fut = match maybe_mac_address {
        None => Either::Left(get_instance()),
        Some(_) => Either::Right(get_instance_by_mac(maybe_mac_address.unwrap())),
    };

    let desk = rt.block_on(async { desk_fut.await });
````Either` is a very useful building block, so it's probable that a library you're using already pulls it in as a dependency anyway.
bright orbit
#

(pushed what I did to the repo)

gritty ember
#

The two functions return Future<Output = impl Device>? gimme a second to check

#

Oh they do

#

Yeah, that ruins thins a little

#

I was relying on the futures being different types with the same output

#

As-is, copying and changing the functions is probably better

#

you could box-dyn the problem away, I guess