Is there any way to make something externally private but internally public to the crate itself?

In one of my projects, I have a helpers module. Basically, I want helpers to be accessible to every module within the crate but not visible to the library users.
Is this possible with rust's module system?

Use pub(crate).

1 Like

where do i exactly use it ?

You replace pub with pub(crate), for example pub fn foo() {} to pub(crate) fn foo() {} or pub struct Bar {} with pub(crate) struct Bar {}

1 Like

Well, if you want your fn floobaroo() accessible to the world, you'd use pub fn floobaroo(). In your case, use pub(crate) fn floobaroo(). See https://doc.rust-lang.org/book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#modules-as-the-privacy-boundary.

that makes sense thank you both so much. For some reason i skipped that part of the book seems like.

Note that in the future there may be the crate visibility modifier, which essentially does the same thing. Here is a link to the unstable book page on it.

2 Likes

well, it's nice to hear that but also sounds a bit unnecessary, isn't it? I mean there's already a way to do it. Will it add any value?

Well, I believe that the rationale is that pub(crate) isn't very nice and logical syntax, seeing as there is already the use of the pub keyword and therefore making crate a visibility modifier would be fitting.

actually yes it would make the code more readable at first glance

Additionally, consider pub(crate) relative to pub fn. Writing out pub(crate) fn is probably less ergonomic and so less likely to be used. However, it seems that holding things more private is something that we want to encourage since it aids maintainability in general. In that light, crate fn is a almost a bribe towards fostering good habits. :wink:

1 Like

As a side note remember that an item's visibility (unless reexported through, for instance, a pub use) is equal to the minimum / the intersection of its visibility with its parents' visibility.

Example

Suppose you pub(in crate) (I find it more readable than pub(crate)) your utils module:

pub(in crate)
mod utils;

Then, within your utils module, all its items can be pub. Since the containing utils module is "private" for users of your lib, so will be its containing elements, despite their declared "pub-ness"

This is specially useful when you need to leak a type in some public function's signature: since it needs to be pub, the trick is to wrap it in a private module. This is currently the only way to "seal" traits (i.e. prevent downstream crates from implementing it) that I know of. Example.

I'm not sure you should be pointing end users at still-under-discussion unstable features that may just be removed. pub(crate) exists today, it's fine, and not everyone wants to see crate on its own become a visibility modifier. I thought that crate_visibility_modifier was unlikely to be stablized because it creates syntax that's stupid-looking or even ambiguous in certain cases.

1 Like

Oh dear that looks like a mess. :sweat_smile: I guess I shouldn't be pointing to unstable pages without reading into the fine details.

1 Like