You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tic_tac_toe.rs
    path of file: ./repos/freya/examples
    
    the code of the file until where you have to start completion: #![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

use freya::prelude::*;

fn main() {
    launch(app);
}

#[derive(Clone, Debug, PartialEq)]
enum Player {
    X,
    O,
}

impl Player {
    fn change_turn(&mut self) {
        match self {
            Self::O => *self = Self::X,
            Self::X => *self = Self::O,
        }
    }
}

struct Board {
    pub winner: Option<Player>,
    pub board: Vec<Vec<Option<Player>>>,
    pub size: usize,
}

impl Board {
    pub fn new(size: usize) -> Self {
        Self {
            winner: None,
            size,
            board: vec![vec![None; size]; size],
        }
    }

    pub fn put_player(&mut self, player: Player, row: usize, col: usize) {
        *self.board.get_mut(row).unwrap().get_mut(col).unwrap() = Some(player);
        self.evaluate_board();
    }

    pub fn get_player(&mut self, row: usize, col: usize) -> Option<Player> {
        self.board.get(row)?.get(col)?.clone()
    }

    pub fn evaluate_board(&mut self) {
        // Horizontal checks
        for row in self.board.iter() {
            let is_row_filled_with_x = row.iter().all(|p| *p == Some(Player::X));
            let is_row_filled_with_o = row.iter().all(|p| *p == Some(Player::O));

            if is_row_filled_with_x {
                self.winner = Some(Player::X);
                return;
            } else if is_row_filled_with_o {
                self.winner = Some(Player::O);
                return;
            }
        }

        // Vertical checks
        for col_n in 0..self.size {
            let is_col_filled_with_x = self
                .board
                .iter()
                .all(|row| *row.get(col_n).unwrap() == Some(Player::X));
            let is_col_filled_with_o = self
                .board
                .iter()
                .all(|row| *row.get(col_n).unwrap() == Some(Player::O));

            if is_col_filled_with_x {
                self.winner = Some(Player::X);
                return;
            } else if is_col_filled_with_o {
                self.winner = Some(Player::O);
                return;
            }
        }

        // Diagonal checks
        for (row_n, row) in self.board.clone().iter().enumerate() {
            for (col_n, _) in row.iter().enumerate() {
                let lines = match row_n {
                    0 if col_n < 2 => vec![(
                        (row_n, col_n),
                        (row_n + 1, col_n + 1),
                        (row_n + 2, col_n + 2),
                    )],
                    0 if col_n > 2 => vec![(
                        (row_n, col_n),
                        (row_n - 1, col_n - 1),
                        (row_n - 2, col_n - 2),
                    )],
            
    
    pub fn evaluate_board(&mut self) {
        // Horizontal checks
        for row in self.board.iter() {
            let is_row_filled_with_x = row.iter().all(|p| *p == Some(Player::X));
            let is_row_filled_with_o = row.iter().all(|p| *p == Some(Player::O));

            if is_row_filled_with_x {
                self.winner = Some(Player::X);
                return;
            } else if is_row_filled_with_o {
                self.winner = Some(Player::O);
                return;
            }
        }

        // Vertical checks
        for col_n in 0..self.size {
            let is_col_filled_with_x = self
                .board
                .iter()
                .all(|row| *row.get(col_n).unwrap() == Some(Player::X));
            let is_col_filled_with_o = self
                .board
                .iter()
                .all(|row| *row.get(col_n).unwrap() == Some(Player::O));

            if is_col_filled_with_x {
                self.winner = Some(Player::X);
                return;
            } else if is_col_filled_with_o {
                self.winner = Some(Player::O);
                return;
            }
        }

        // Diagonal checks
        for (row_n, row) in self.board.clone().iter().enumerate() {
            for (col_n, _) in row.iter().enumerate() {
                let lines = match row_n {
                    0 if col_n < 2 => vec![(
                        (row_n, col_n),
                        (row_n + 1, col_n + 1),
                        (row_n + 2, col_n + 2),
                    )],
                    0 if col_n > 2 => vec![(
                        (row_n, col_n),
                        (row_n - 1, col_n - 1),
                        (row_n - 2, col_n - 2),
                    )],
                    1 if col_n >= 1 => vec![
                        (
                            (row_n - 1, col_n - 1),
                            (row_n, col_n),
                            (row_n + 1, col_n + 1),
                        ),
                        (
                            (row_n - 1, col_n + 1),
                            (row_n, col_n),
                            (row_n + 1, col_n - 1),
                        ),
                    ],
                    2 if col_n >= 2 => vec![(
                        (row_n - 2, col_n - 2),
                        (row_n - 1, col_n - 1),
                        (row_n, col_n),
                    )],
                    2 if col_n < 2 => vec![(
                        (row_n + 2, col_n + 2),
                        (row_n + 1, col_n + 1),
                        (row_n, col_n),
                    )],
                    _ => vec![],
                };

                for (top, mid, bot) in lines {
                    let line = vec![
                        self.get_player(top.0, top.1),
                        self.get_player(mid.0, mid.1),
                        self.get_player(bot.0, bot.1),
                    ];

                    let is_line_filled_with_x =
                        line.iter().all(|player| *player == Some(Player::X));
                    let is_line_filled_with_o =
                        line.iter().all(|player| *player == Some(Player::O));

                    if is_line_filled_with_x {
                        self.winner = Some(Player::X);
                        return;
                    } else if is_line_filled_with_o {
                        self.winner = Some(Player::O);
                        return;
                    }
                }
            }
        }
    }