Background
I am writing a library, some related code are shown below:
pub struct MyStruct1;
pub struct MyStruct2;
pub enum MyEnum {
Variant1(MyStruct1),
Variant2(MyStruct2)
}
// out of this crate
fn foo(my_enum: Rc<RefCell<MyEnum>>) {
match &*my_enum.borrow() {
Variant1(my_struct1) => { /* do something */ },
Variant2(my_struct2) => { /* do something */ }
}
}
Target
MyEnum
is always used wrapped in Rc<RefCell<MyEnum>>
. So I want to hide it in a newtype struct as described in is-it-possible-to-implement-methods-on-type-aliases:
//make this only public to crate
pub(crate) enum MyEnum;
pub struct ExposedMyEnum(pub(crate) Rc<RefCell<MyEnum>>);
And I don't want others who uses my crate to know the existence of Rc<RefCell<>>
.
Problem
If I use ExposedMyEnum
to hide the annoying Rc<RefCell<MyEnum>>
, I can't do pattern matching as foo
do out of this crate.
Ungraceful solution
Change the original code to
struct MyStruct1;
struct MyStruct2;
pub struct ExposedMyStruct1(pub(crate) Rc<RefCell<MyStruct1>>);
pub struct ExposedMyStruct2(pub(crate) Rc<RefCell<MyStruct2>>);
pub enum MyEnum {
Variant1(ExposedMyStruct1),
Variant2(ExposedMyStruct1)
}
// out of this crate
fn foo(my_enum: &MyEnum) {
match &my_enum {
Variant1(my_struct1) => { /* do something */ },
Variant2(my_struct2) => { /* do something */ }
}
}
I need to create newtype structs for each variant, which is not graceful.