As projects grow I tend to end up in the situation where I have tests and examples that need a substantial amount of helper functions to set things up. I stick this boilerplate stuff in a helpers/mod.rs in both tests and examples. However, there's usually a lot of overlap between the two, and it's kind of annoying to maintain them.
I once tried to put the boilerplate stuff in a dedicated crate, sort of like this:
name = "foo"
[dev-dependencies]
bar = { workspace = true }
(foo is the main library).
name = "bar"
[dependencies]
foo = { workspace = true }
(bar is a library intended to collect things like the contents of the helpers submodule).
That is to say, bar (boilerplate) depends on foo (main library), and foo has a dev dependency on bar.
I didn't get this to work, and I don't know why. (What I think happened was that I (stupidly) assumed it wasn't going to work, and I probably made some other, unrelated, error, and when I saw an error I didn't read it and just assumed it was saying something about a circular dependency).
Well, I just tried this again, and it Just Worked(tm). So all these years I've been doing a lot of extra work for nothing.
Not sure who needs to hear this, but .. actually read the errors, even if you assume you know what it is.
Also, for those who don't know -- you can put your tests/examples boilerplate in a separate crate. ![]()