1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
extern crate nzsc2p;
use nzsc2p::two_player_game::{
    NZSCTwoPlayerGame,
    Phase,
};
use nzsc2p::players::{
    CharacterlessPlayer,
    BoosterlessPlayer,
    MovelessPlayer,
};
use nzsc2p::streaks::{ CharacterStreak, MoveStreak, };

use std::fmt::Display;

mod tests;

fn opt_to_json_null_or_string<T: Display>(opt: Option<T>) -> String {
    if let Some(some) = opt {
        format!("\"{}\"", some)
    } else {
        "null".to_string()
    }
}

fn character_streak_to_json_obj(streak: &CharacterStreak) -> String {
    format!(
        r#"{{"times":{},"character":{}}}"#,
        streak.times,
        opt_to_json_null_or_string(streak.repeated_character)
    )
}

fn move_streak_to_json_obj(streak: &MoveStreak) -> String {
    format!(
        r#"{{"times":{},"move":{}}}"#,
        streak.times,
        opt_to_json_null_or_string(streak.repeated_move)
    )
}

fn vec_to_json_array<T: Display>(vec: Vec<T>) -> String {
    let with_quotes: Vec<String> = vec.into_iter().map(|x| format!("\"{}\"", x)).collect();
    let mut array = "[".to_string();
    for item in &with_quotes {
        array.push_str(item);
        array.push_str(",")
    }
    if with_quotes.len() > 0 {
        array.pop();
    }
    array.push_str("]");
    array
}

fn characterless_player_to_phase_json_obj(player: &CharacterlessPlayer) -> String {
    format!(
        r#"{{"points":{},"waits":{},"character_streak":{},"selected_character":{}}}"#,
        player.points,
        player.waits,
        character_streak_to_json_obj(&player.character_streak),
        opt_to_json_null_or_string(player.selected_character)
    )
}

fn boosterless_player_to_phase_json_obj(player: &BoosterlessPlayer) -> String {
    format!(
        r#"{{"points":{},"waits":{},"character":"{}","selected_booster":{}}}"#,
        player.points,
        player.waits,
        player.character,
        opt_to_json_null_or_string(player.selected_booster)
    )
}

fn moveless_player_to_phase_json_obj(player: &MovelessPlayer) -> String {
    format!(
        r#"{{"points":{},"waits":{},"character":"{}","booster":"{}","move_streak":{},"destroyed_moves":{},"selected_move":{}}}"#,
        player.points,
        player.waits,
        player.character,
        player.booster,
        move_streak_to_json_obj(&player.move_streak),
        vec_to_json_array(player.destroyed_moves.clone()),
        opt_to_json_null_or_string(player.selected_move)
    )
}

fn characterless_player_to_question_json_obj(player: &CharacterlessPlayer) -> String {
    if let Some(ref _selected_character) = &player.selected_character {
        r#"{"question":null}"#.to_string()
    } else {
        format!(r#"{{"question":"CHOOSE_CHARACTER","available_characters":{}}}"#, vec_to_json_array(player.available_characters()))
    }
}

fn boosterless_player_to_question_json_obj(player: &BoosterlessPlayer) -> String {
    if let Some(ref _selected_booster) = &player.selected_booster {
        r#"{"question":null}"#.to_string()
    } else {
        format!(r#"{{"question":"CHOOSE_BOOSTER","available_boosters":{}}}"#, vec_to_json_array(player.available_boosters()))
    }
}

fn moveless_player_to_question_json_obj(player: &MovelessPlayer) -> String {
    if let Some(ref _selected_move) = &player.selected_move {
        r#"{"question":null}"#.to_string()
    } else {
        format!(r#"{{"question":"CHOOSE_MOVE","available_moves":{}}}"#, vec_to_json_array(player.available_moves()))
    }
}

pub fn phase_as_json(game: &NZSCTwoPlayerGame) -> String {
    match &game.phase {
        &Phase::CharacterChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"CHARACTER_CHOOSING","a":{},"b":{}}}"#,
                characterless_player_to_phase_json_obj(a),
                characterless_player_to_phase_json_obj(b)
            )
        },

        &Phase::BoosterChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"BOOSTER_CHOOSING","a":{},"b":{}}}"#,
                boosterless_player_to_phase_json_obj(a),
                boosterless_player_to_phase_json_obj(b)
            )
        },

        &Phase::MoveChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"MOVE_CHOOSING","a":{},"b":{}}}"#,
                moveless_player_to_phase_json_obj(a),
                moveless_player_to_phase_json_obj(b)
            )
        },

        &Phase::GameOver(ref a, ref b) => {
            format!(
                r#"{{"phase":"GAME_OVER","a":{},"b":{}}}"#,
                a,
                b
            )
        },
    }
}

pub fn question_as_json(game: &NZSCTwoPlayerGame) -> String {
    match &game.phase {
        &Phase::CharacterChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"CHARACTER_CHOOSING","a":{},"b":{}}}"#,
                characterless_player_to_question_json_obj(a),
                characterless_player_to_question_json_obj(b)
            )
        },

        &Phase::BoosterChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"BOOSTER_CHOOSING","a":{},"b":{}}}"#,
                boosterless_player_to_question_json_obj(a),
                boosterless_player_to_question_json_obj(b)
            )
        },

        &Phase::MoveChoosing(ref a, ref b) => {
            format!(
                r#"{{"phase":"MOVE_CHOOSING","a":{},"b":{}}}"#,
                moveless_player_to_question_json_obj(a),
                moveless_player_to_question_json_obj(b)
            )
        },

        &Phase::GameOver(ref _a, ref _b) => {
            format!(
                r#"{{"phase":"GAME_OVER","a":{0},"b":{0}}}"#,
                r#"{"question":null}"#
            )
        },
    }
}