Home > database >  Exposing only a concrete variant of a generic private type in a Rust library
Exposing only a concrete variant of a generic private type in a Rust library

Time:12-04

I have a Rust library crate with code that is structured as follows:

pub struct Foo<X> {
    x: X,
}

pub fn foo() -> Foo<u32> {
    // ...
}

//   private functions

In particular, while the lib uses different variants of Foo internally (e.g. Foo<u8>, Foo<u32>), Foo only occurs in the lib's public API as Foo<u32>.

Exposing the generic Foo as I currently do makes the lib's public API and its documentation unnecessarily complex: the user will never get a Foo from the library that is not a Foo<u32>. Therefore, I'd like to somehow only expose and publicly document Foo<u32> (ideally under a different, non-generic name, e.g. Bar) and make Foo private.

I've tried using a type alias (type Bar = Foo<u32>), but it seems that those are automatically expanded by cargo doc (and they also don't seem to have separate visibility).

I could probably copy the definition of Foo<X> and call it Bar instead, and then implement something like From<Foo<u32>> for Bar. However, my actual definition of Foo<X> is fairly complex, so I'd like to avoid that.

Is there another way to achieve my goal?

CodePudding user response:

You can expose the type from the parent module as follows:

mod prelude {
    mod foo_mod {
        pub struct Foo<X> {
            x: X,
        }

        impl Foo<u32> {
            pub fn foo() -> u32 {
                32
            }
        }

        impl Foo<u8> {
            pub fn foo() -> u8 {
                8
            }
        }
    }

    pub type FooBar = foo_mod::Foo<u32>;
}


fn main() {
    use prelude::FooBar; // we can use this
    use prelude::foo_mod::Foo; // we cannot use this
}

Playground

  • Related