Make a function pub within the crate but not outside?


#1

I have a struct with a constructor that needs to be called from another module in my crate, but that should not be possible to call from outside the crate, while the struct itself and other methods in it needs to be public. Is that possible?

So what I have in my crate is something like this:

fn do_wrapped(todo: F) -> MyResult<T>
    where F: FnOnce(&mut context) -> MyResult<T>
{
    let context = Context::new(...);
    ...
    try!(doit(context));
    ...
}

pub struct Context {
    fn new(...) { ... }
    pub fn foo() { ... }
}

And I want users of the crate to be able to do:

do_wrappet(|context| {
    context.foo();
});

I want to put do_wrapped in another module that stuct Context (my actual do_wrapped is a method on another struct). To be able to do that it seems I have to make Context::new public. Is there a way around this?


#2

A private item is still available to all submodules. So a private item in the root of the crate is usable by the whole crate, for example a private function that creates a new Context.


#3

Make new a freestanding function:

pub fn new_context(...) { ... }

pub struct Context {
    
    pub fn foo() { ... }
}

There is an rfc in flight, which would allow you to write pub(crate) fn new: https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md


#4

Notice also that the above-linked RFC is already implemented behind an unstable feature gate, for those who are particularly eager to try it out:

// this compiles only on nightly rust

// in lib.rs or main.rs...
#![feature(pub_restricted)]

// elsewhere...
pub(crate) fn foo() {}

#5

Thanks, I did so and it seems to work perfectly!