Lib root `pub use` will only work if the mod is also pub

Hiya :slight_smile:

So I want to make a nice and tidy interface for my library crate. So instead letting a user have access to sub-modules, I want them to be able to reach structs/etc from the library root (lib.rs):

mod sh2;
pub use sh2::Sh2;

And in the client code, I try to access about thusly:

use libname;
let sh2 = libname::Sh2::new();

However, this will fail with:

error: module sh2 is private

Which was the whole point.

Doing a pub mod sh2; makes things compile, but we loose the encapsulation.

So was this by design? Am I doing something wrong?

It should work if Sh2 is public, even if sh2 is private.

mod internal {
    pub mod exposed {
        pub const FOO: u32 = 1;
    }
}

pub use internal::exposed;

The same thing works for me. Does your code have use libname instead of extern crate libname?

#!/bin/bash

cargo new libname

cat > libname/src/lib.rs <<-'EOF'
    mod sh2;
    pub use sh2::Sh2;
EOF

cat > libname/src/sh2.rs <<-'EOF'
    #[derive(Debug)]
    pub struct Sh2;
    impl Sh2 {
        pub fn new() -> Self {
            Sh2
        }
    }
EOF

cargo new --bin ties

cat >> ties/Cargo.toml <<-'EOF'
    libname = { path = "../libname" }
EOF

cat > ties/src/main.rs <<-'EOF'
    extern crate libname;
    fn main() {
        println!("{:?}", libname::Sh2::new());
    }
EOF

cargo run --manifest-path ties/Cargo.toml

No, in my case Sh2 is pub. I should think Sh2 should always be pub for things to even work. You can't access a private struct in a pub mod I don't think.

I'm sure the examples in say 'the book' work, in which submodules of library submodules can be exported in this way. But specifically in the library root (lib.rs) this does not seem to work.

Could you share the full code?

Thanks for your thorough reply. And sorry to waste your time, I'm an idiot. There was a use libname::sh2 in the root of the client lib. I should have made my own stripped down example first.

Very much thanks for the help though!