Inter-modules visibility of functions in a library

#1

Hi,

I split my library into several modules, where a module(s) uses methods from another.
To do so, I added the pub modifier to those methods. However, from a user point-of-view of this library, I just want few methods to be visible; all the other were made public but with an internal usage in mind.

Is there a way to improve the user-facing API in this use case ?

Thanks

2 Likes

#2

You can make things public within the crate they were defined by using

crate fn foo() {

instead of

pub fn foo() {

You can also make things public within specific modules in the crate using

pub(in path::to::module) fn foo() {

Note that this only works in Rust 2018.

2 Likes

#3

Is there a recommended article to supplement the Rust book for understanding the module system and use vs. mod statements a bit more intuitively?

It’s still not clear to me how they interact and when I want to use super:: or even crate::, and for that matter importing crates vs using them.

No doubt there are posts here and these things become clearer over time as I run into it when building larger projects that need it, but it is a bit frustrating when starting out that I can’t split my code up with about a bit of “guesswork” and I’d guess this is a common issue for others new to Rust.

0 Likes

#4

Use cargo doc to view how your library appears to others.

Things you can do:

  • pub(crate) makes it available only to your crate, but not outside it.
  • pub in a private module is not accessible from outside, so it’s equivalent to pub(crate)
  • You can do pub use private_module::foo to make the item available where the pub use is. It’s very useful to allow you to have any module organization of your library that you like, but export only a small, flat interface.
0 Likes

#5

Thanks, using crate as the visibility modifier fits my need as I wanted to (1) hide methods that are used within the crate; and (2) display the docs of some enums.

I am writing a parser and therefore:

  • I want the ast to be built from one function
  • I want the components of that ast, spread among several modules, to be visible for the user; methods that were used to create internal nodes of the tree should be hidden.

Tangent to the initial question (tell me if that should be a separate thread), I would like a method to create those internal nodes accessible from a separate crate, however only visible from my tests; the purpose is to simplify testing by making it more modular.

Would that be possible ?

Thanks

0 Likes

#6

If you write your tests like so in the same file:

//lib.rs
fn code_i_want_to_test() {/**/}
//...
#[cfg(test)]
fn my_test() {
    code_i_want_to_test();
    //...
}

then you will be able to access your methods in a deeper level without having to worry about visibility modifiers.

Note that I have seen this in stdlib, and so I’m not sure if it’s unique to it, but it seems to be a good idea

0 Likes