Reputation: 629
Currently, I'm trying to blanket implement a public trait on any struct that implement a private trail, but i get compiler warning: private trait `mod_b::PrivateTrait` in public interface (error E0445)
Is there anyway to fix this?
main.rs:
trait PublicTrait {}
mod mod_b
{
use PublicTrait;
trait PrivateTrait {}
impl<T: PrivateTrait> PublicTrait for T {}
}
pub fn main ()
{
}
Upvotes: 4
Views: 1772
Reputation: 2259
I accomplished this two ways: with a private fn
outside of the trait
in the same module (like you might do in JavaScript); and with a private trait
and pub trait
in the same module. In both cases, the solution involved implementing a generic and using the Sized
constraint.
Private fn
:
pub trait MyPublicTrait: Sized {
fn get_msg(&self) -> &str { "Hello from" }
fn do_something(&self) {
do_something_impl(self);
}
}
fn do_something_impl<T>(a: &T)
where T: MyPublicTrait
{
println!("{} private fn", a.get_msg());
}
Private trait
:
trait MyPrivateTrait {
fn do_something_impl(&self);
}
pub trait MyPublicTrait: Sized {
fn get_msg(&self) -> &str { "Hello from" }
fn do_something(&self) {
self.do_something_impl();
}
}
impl<T: MyPublicTrait> MyPrivateTrait for T {
fn do_something_impl(&self) {
println!("{} private trait", self.get_msg());
}
}
The second one seemed confusing to me at first, because MyPublicTrait
is using do_something_impl
before it "knows" that Self
will always implement MyPrivateTrait
. But apparently the compiler knows what we're trying to say: that do_something_impl
is always there for any MyPublicTrait
because MyPrivateTrait
is implemented for all T: MyPublicTrait
. And vice versa, get_msg
is available for MyPrivateTrait
because any T
will always be a MyPublicTrait
.
And from the perspective of calling code outside of this module, the methods declared in MyPrivateTrait
will never be available because you can't use
a private trait
.
Upvotes: 1
Reputation: 174
You need to make the PrivateTrait
public
trait PublicTrait {}
mod mod_b {
use crate::PublicTrait;
pub trait PrivateTrait {}
impl<T: PrivateTrait> PublicTrait for T {}
}
fn test<T: PublicTrait>(_: T){
println!("public")
}
struct Private;
impl mod_b::PrivateTrait for Private {}
pub fn main() {
test(Private);
}
Or to keep PrivateTrait
private in mod_b
trait PublicTrait {}
mod mod_b {
use crate::PublicTrait;
trait PrivateTrait {}
impl<T: PublicTrait> PrivateTrait for T {}
}
fn main() {}
Upvotes: 3