Rust: How to make struct generic over two types for information that is sometimes hidden

Advertisements

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?

edit: added another field to GameState to make the objective more clear.

>Solution :

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>,
}

Leave a ReplyCancel reply