Sub-modules using private parent struct in public interface

I have started experimenting with encapsulation with Rust and have come across an issue where I want to use a struct which is private in the parent module (not public) in a sub module but I want the parent module to be able to call the child function so it must be public. Unfortunately this triggers an error. The sub-module will not be exported publicly outside of the parent modules visibility either.

Below is a toy example of the problem I encountered.

fn main() {
    parentmod::its_complicated();
}

mod parentmod {

    pub fn its_complicated() -> u32 {
        let param = PrivateStruct{field: 50};
        childmod::do_something(&param);
        param.field
    }
    
    struct PrivateStruct {
        field: u32,
    }
    
    mod childmod {
        pub fn do_something(_param: &super::PrivateStruct) {
            println!("do_something");
        }
    }
}

Error message:

   |
14 |       struct PrivateStruct {
   |       - `parentmod::PrivateStruct` declared as private
...
19 | /         pub fn do_something(_param: &super::PrivateStruct) {
20 | |             println!("do_something");
21 | |         }
   | |_________^ can't leak private type

Unless I am missing something, I want the Rust compiler to recognize that childmod is not being exported publicly outside of parentmod so any use of structs private to parentmod in the public interface of childmod is ok since any module which has visibility to childmod (i.e. a sibling module or parentmod itself) can also see any private structs.

Short of not doing this (which is always an option), is there a way to have this structure?

You can mark do_something as pub(super) to indicate it's only visible to the parent module. This compiles.

You can also use pub(crate) or even just pub. Note that since the struct is in a private module, it will not be visible outside the crate in either case.

Thank you very much. This is exactly the syntax I was looking for.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.