Rust doesn't have any sort of reflection or dynamic type introspection, so you can't avoid implementing the trait for each struct individually if you want to have struct-specific data.
If the boilerplate is the problem, then create a derive macro.
The problem with your example is that you don't own the Debug trait or all types (the uncovered T parameter), so your implementation of Debug can't be accepted as it would result in multiple implementations for the same type (e.g. str already has a Debug implementation which you cannot override). The particular rules around what blanket implementations you can and can't write are known as the orphan rules.
You could wrap T in a local newtype. Or you could put the functionality in your own trait.
I understand orphan rule (at least I think so) but why isn't it possible to overcome orphan rule when my trait is private? In that case only I can be the owner of all types implementing my trait, so there should be no conflicts with apps/libs using my library.
In that case compiler should just forbid implementing Debug for all structs that implement Identifiable.
Problem is, what if you implement Identifiable for type A and another crate, with no relation with your crate, implements Debug for A. This means that whoever tries to use both crates at the same time will get a compile error, and avoiding this was deemed more important than lifting the limitations of the orphan rule (which is what's preventing your impl).
is untrue as you can implement your private trait for types you don't own (like str).
I have also wished for some way to specify my blanket implementation should only apply to local types, but that doesn't exist. In those cases I generally fall back to some sort of macro.
is untrue as you can implement your private trait for types you don't own (like str ).
well... in that case compiler should throw an error (aka my last sentence). Also str can't implement private Identifiable outside of my crate, so all errors are on me.
trait B {} // no pub, so it's private
impl B for a::A {}
impl<T: B> Debug for T {}
crate c, depends on crate a:
trait C {} // no pub, so it's private
impl C for a::A {}
impl<T: C> Debug for T {}
Under your proposal both crate b and crate c compile alone because they essentially do the same thing, however the moment crate d depends on both of them it gets a compile error due to two implementations of Debug for a::A.
So, when you say
this is the same reason you can't write the implementation in the first post.
yeah... I didn't think of this scenario
It is probably possible to allow when both private trait + private struct but it is way to niche case to worth the effort...