I am making a multiplayer game, where the server has full knowledge of the game state (Sure
), but the client only sees a part of it (SometimesSure
, parts of the world are hidden, e.g. cards in a deck). I want to use the same GameState
struct though and make it generic over those two cases:
enum SometimesSure<T> {
Hidden,
Visibile(T),
}
struct Sure<T>(T);
struct GameState {
pub map_state: MapState,
pub player_states: PlayerStates,
}
where MapState
and PlayerStates
should be on the client:
struct MapState {
pub tiles: Vec<SometimesSure<u8>>,
}
struct PlayerStates {
pub points: SometimesSure<bool>,
pub name: SometimesSure<String>,
}
and on the server:
struct MapState {
pub tiles: Vec<Sure<u8>>,
}
struct PlayerStates {
pub points: Sure<bool>,
pub name: Sure<String>,
}
How can I solve this with Generics or Associated Types?
CodePudding user response:
Ideally you would use higher kinded types here, but Rust does not support the concept. However, since generic associated types (GATs) were recently stabilized, you can use a helper trait (StateType
in the code below) with a generic associated type to fulfill the same purpose:
trait StateType {
type Type<T>;
}
struct ClientStateType;
impl StateType for ClientStateType {
type Type<T> = SometimesSure<T>;
}
struct ServerStateType;
impl StateType for ServerStateType {
type Type<T> = Sure<T>;
}
struct MapState<S: StateType> {
pub tiles: Vec<S::Type<u8>>,
}
struct GameState<S: StateType> {
pub map_state: MapState<S>,
}