Невозможно сделать это прямым способом, потому что они бывают двух разных типов: в этом-то и весь смысл вашего кода. Чтобы упростить это, я бы сделал это в 2 шага, с обобщенным c переходом, являющимся вторым:
use core::marker::PhantomData;
struct Foo<State> {
a: i32,
b: i32,
c: i32,
//...
state: PhantomData<State>,
}
struct SourceState;
struct DestinationState;
impl<Src> Foo<Src> {
fn transition<Dest>(self) -> Foo<Dest> {
let Foo {a, b, c, state: _} = self;
Foo { a, b, c, state: PhantomData }
}
}
impl Foo<SourceState> {
fn to_destination_state(mut self, extra: ()) -> Foo<DestinationState> {
// Do whatever you want with self
self.transition()
}
}
В качестве альтернативы, вы можете абстрагировать тот факт, что у вас есть состояние:
mod stateful {
use core::marker::PhantomData;
pub struct Stateful<T, State> {
pub data: T,
state: PhantomData<State>,
}
impl<T, SrcState> Stateful<T, SrcState> {
pub fn transform<DestState>(self) -> Stateful<T, DestState> {
let Stateful { data, state: _ } = self;
Stateful {
data,
state: Default::default(),
}
}
}
}
struct Data {
a: i32,
b: i32,
c: i32,
}
struct SourceState;
struct DestinationState;
type Foo<State> = stateful::Stateful<Data, State>;
impl Foo<SourceState> {
fn to_destination_state(mut self, extra: ()) -> Foo<DestinationState> {
// Do whatever you want with self.data
self.transform()
}
}