Imagine that you pull in crate
foo as a dependency. It has a
foo::Error for its own errors, so you set up a
From conversion to do implicit conversion from
foo::Error to your own library/application error.
At some point you call
foo::Foo::do_something(), and the implicit conversion doesn't work. It turns out that
bar as a dependency, and
Foo::do_something() is a very thin wrapper around some function in
bar, and for whatever reason
foo's developer chose to have the wrapper be so thin that it returns
I have encountered this in the wild, so it's not hypothetical -- but I'd say its rare (as far as the crates/functions I have used). Personally I tend to wrap other crate's
Error's in my own errors, because I don't want end users to have to pull in separate crates just to get access to
There is a sort of a middle-ground, I guess: Re-export the dependencies, so the developer doesn't need to explicitly import them in their own
Where on the transparent-to-opaque scale do we want sub-dependencies to, generally speaking, be in the ecosystem?
Back-story: I'm in a situation where I set out to remove some in-crate objects and use dependencies instead. I am pleased with the result, except for one particular place where I expose a foreign
Error. I can work around this by adding an error-conversion wrapper -- but this is the sort of thing I set out to clean up. So it got me questioning why I put so much effort into hiding sub-dependencies?
I have always treated dependencies opaquely, even back in the C/C++ days -- it never really occurred to me to not do it in Rust. But apart from "following tradition" and "being idiomatic", are there technical reasons why crates tend to be opaque? What manner of can-of-worms would one be opening up if one would start to lean on the more transparent side of things?