Browse Source

Nearly there

ag-yep
Taylor Bockman 7 years ago
parent
commit
be2ca9fc75
  1. 15
      src/lib.rs
  2. 53
      src/options.rs
  3. 24
      tests/lib.rs

15
src/lib.rs

@ -2,7 +2,13 @@
//! The engine is fully generic. By specifying a valid reader and writing you can send the messages to STDIN
//! and STDOUT, per the standard - or to memory for testing.
mod commands;
// BIG TODO: Change pub struct members to private and use getters/setters. DO THIS FOR EVERYTHING AFTER YOU
// IMPLEMENT OPTION SENDING.
// ALSO CHANGE COMMANDS TO HAVE A CONSTANTS SUBMODULE LIKE OPTIONS
pub mod commands;
pub mod options;
use std::io::{BufRead, Write};
use std::vec;
@ -13,7 +19,7 @@ pub struct Engine<'a, R, W> {
pub author: &'a str,
pub reader: R,
pub writer: W,
pub engine_options: Vec<EngineOption>,
pub engine_options: Vec<options::EngineOption>,
}
/// Notes to delete later:
@ -32,7 +38,8 @@ pub struct Engine<'a, R, W> {
/// worry about calling "boot up" prior to their main engine loop.
///
///
/// TODO: THE NEXT THING - THE PARSER!
/// TODO: THE NEXT THING - THE PARSER! (after putting in getters but _no_ setters and taking away pub fields
/// for all structs in the app if that is idiomatic)
///
/// Additionally this code should have a parser. You call it with the reader supplied and it waits for a command
/// and parses it into a tuple of <token, value>. For example it would parse `setoption` into an option constant
@ -45,7 +52,7 @@ where
W: Write,
{
pub fn new(name: &'a str, author: &'a str,
reader: R, writer: W, engine_options: Vec<EngineOption>) -> Engine<'a, R, W> {
reader: R, writer: W, engine_options: Vec<options::EngineOption>) -> Engine<'a, R, W> {
Engine {
name: name,
author: author,

53
src/options.rs

@ -3,6 +3,10 @@
//! and EngineOption tries to be flexible so it can be reused for each option, which also maintaining some
//! of the nicer parts of typechecking.
use std::collections::HashMap;
pub mod constants {
/// Represents the hash option
pub const HASH: &'static str = "Hash";
@ -28,7 +32,7 @@ pub const UCISHOWCURRLINE: &'static str = "UCI_ShowCurrLine";
pub const UCISHOWREFUTATIONS: &'static str = "UCI_ShowRefutations";
/// Represents the UCI_LimitStrength option
pub const UCISHOWREFUTATIONS: &'static str = "UCI_LimitStrength";
pub const UCILIMITSTRENGTH: &'static str = "UCI_LimitStrength";
/// Represents the UCI_Elo option
pub const UCIELO: &'static str = "UCI_Elo";
@ -39,9 +43,11 @@ pub const UCIANALYSISMODE: &'static str = "UCI_AnalysisMode";
/// Represents the UCI_Opponent option
pub const UCIOPPONENT: &'static str = "UCI_Opponent";
#[derive(Debug)]
}
/// The `EngineOptionType` type used to indicate what type of option the GUI should display
enum EngineOptionType {
#[derive(Copy, Debug, Eq)]
pub enum EngineOptionType {
Check,
Spin,
Combo,
@ -49,42 +55,45 @@ enum EngineOptionType {
TypeString, // `String` is a reserved word so `TypeString` is substituted
}
#[derive(Debug)]
#[derive(Copy, Debug, PartialEq, PartialOrd)]
/// The `EngineOptionData` makes the data type generic so one `EngineOption` can represent everything
/// This would be set to the type of the engine option (ex. i32)
pub enum EngineOptionData {
Int(i32),
Float(f64),
Text(String),
}
#[derive(Debug, Hash, PartialEq)]
/// The `EngineOptionDataType` type used to indicate the type of the `EngineOption` setting
enum EngineOptionDataType {
pub enum EngineOptionDataType {
DefaultVal, // `Default` is reserved so `DefaultVal` is used
Min,
Max,
Var,
}
#[derive(Debug)]
/// The `EngineOptionDataValue` makes the data type generic so one `EngineOption` can represent everything
/// This would be set to the type of the engine option (ex. i32)
struct EngineOptionDataValue<T> {
value: T,
}
#[derive(Debug, PartialEq)]
/// The `EngineOption` type is the overarching type representing a single configurable engine option
struct EngineOption<T> {
name: &'static str,
option_type: EngineOptionType,
option_data: HashMap<EngineOptionDataType, EngineOptionDataValue<T>>,
pub struct EngineOption {
pub name: &'static str,
pub option_type: EngineOptionType,
pub option_data: HashMap<EngineOptionDataType, EngineOptionData>,
}
impl PartialEq for EngineOption {
pub fn eq(&self, other: EngineOption) {
// TODO: Implement equality on the EngineOption struct and write tests for it.
}
impl EngineOption {
/// Constructs a new EngineOption of type T
pub fn new(name: &'static str, option_type: EngineOptionType,
option_data: HashMap<EngineOptionDataType, EngineOptionData>) -> EngineOption {
EngineOption { name, option_type, option_data }
}
impl EngineOption {
pub fn option_string(&self) -> String {
// TODO: Implement this to save this when looping through and sending options
// TODO: This should be tested in isolation as well
// This should handle the case where optional min max var are specified as well.
// pattern match the engine option type and convert it to the correct string.
format!("PUT THE FULL COMMAND STRING HERE!");
format!("PUT THE FULL COMMAND STRING HERE!")
}
}

24
tests/lib.rs

@ -1,6 +1,8 @@
extern crate uci;
use uci::Engine;
use uci::options::constants;
use uci::options::{ EngineOption, EngineOptionType, EngineOptionDataType, EngineOptionData };
use std::str;
#[test]
@ -8,7 +10,7 @@ fn instantiate_new_engine() {
let input = b"UNUSED";
let mut output = Vec::new();
let e = Engine::new("test_name", "test", &input[..], &mut output);
let e = Engine::new("test_name", "test", &input[..], &mut output, vec!());
assert_eq!(e.name, "test_name");
assert_eq!(e.author, "test");
}
@ -20,7 +22,7 @@ fn send_identification_data() {
// We need to scope this so that the mutable borrow ends and we can test it safely
{
let mut e = Engine::new("test_name", "test", &input[..], &mut output);
let mut e = Engine::new("test_name", "test", &input[..], &mut output, vec!());
e.identify();
}
@ -36,10 +38,26 @@ fn send_readyok() {
let input = b"UNUSED";
let mut output = Vec::new();
{
let mut e = Engine::new("test_name", "test", &input[..], &mut output);
let mut e = Engine::new("test_name", "test", &input[..], &mut output, vec!());
e.ready();
}
assert_eq!(str::from_utf8(&output).unwrap_or("Unwrapping output failed in send_readyok"),
"readyok\n");
}
#[test]
fn engine_option_equality() {
let name = constants::HASH;
let option_type = EngineOptionType::Check;
let option_data =
[(EngineOptionDataType::DefaultVal, EngineOptionData::Int(1)),
(EngineOptionDataType::Min, EngineOptionData::Int(1)),
(EngineOptionDataType::Max, EngineOptionData::Int(128))
].iter().cloned().collect();
let o1 = EngineOption { name, option_type, option_data };
let o2 = EngineOption { name, option_type, option_data };
assert_eq!(o1, o2);
}

Loading…
Cancel
Save