I was just reading Rust Compile Times and Code Graphs | Hacker News Compile Times and Code Graphs
and in particular:
For each unit of business logic
foo
, separate crates for:
- Types: for Plain Old Data, protobuf, traits that users of
foo
implement, etc.- Interface: for the public API without an implementation. 4sq called this
FooService
, mz calls itfoo-client
.- Implementation: for the implementation of the public API. 4sq called this
FooConcrete
, mz calls itfoo
.- Note that not every
foo
will have all three of these, and some will be more complicated, but I’ve found these three to be a reasonable default.
Now, I like this idea. I have one problem: In Rust, aren't all impl
blocks required to be either (1) in same crate as where struct/enum is declared or (2) in same crate as where trait is declared ?
If so, how is it possible to separated out the "implementation" crate from the "types" or "interface" crates ?
Concretely, if:
crate foo_types: pub struct Foo
crate foo_traits: pub trait Bar_T
doesn't Rust compiler require that:
-
"impl Foo" be in "foo_types" and
-
"impl Bar_T for Foo" to be in either foo_types or foo_traits ?
If so, in the article, how are they separating out the implementation crate (and what is in it?)
Thanks!