use std::error::Error; use crate::{ENGINE_AUTHOR, ENGINE_NAME, ENGINE_VERSION}; use std::fmt::Write; use std::sync::{Arc}; use spin::Mutex; #[derive(Default)] pub struct UCIState { debug: bool, is_blocking: bool } impl UCIState { pub fn new() -> Self { Self::default() } } pub fn uci_handle_command(state: Arc>, cmd: String) -> Result> { let cmd_split = cmd.trim().split(' ').collect::>(); match cmd_split[0] { "uci" => Ok(uci_id()), "isready" => Ok(uci_isready(state)), "debug" => Ok(uci_debug(state, &cmd_split)), "ucinewgame" => Ok("".to_string()), _ => Ok(format!("Unrecognized command `{}`, consult the documentation for more information", cmd.trim())) } } pub fn uci_id() -> String { let mut result = String::new(); writeln!(result, "id name {} {}", ENGINE_NAME, ENGINE_VERSION).unwrap(); writeln!(result, "id author {}", ENGINE_AUTHOR).unwrap(); writeln!(result, "uciok").unwrap(); result } pub fn uci_debug(state: Arc>, cmd: &Vec<&str>) -> String { if cmd.len() != 2 { return format!("Unrecognized command `{}`, consult the documentation for more information", cmd.join(" ")) } match cmd[1] { "on" => state.lock().debug = true, "off" => state.lock().debug = false, _ => return format!("Unrecognized command `{}`, consult the documentation for more information", cmd.join(" ")) }; "".to_string() } pub fn uci_isready(state: Arc>) -> String { loop { if !state.lock().is_blocking { break; } } "readyok\n".to_string() }