Skip to main content

gorrosion_gtp/command/
mod.rs

1//! Abstract description of a command
2//! as specified in some external document.
3//!
4//! The submodules (will) provide all the commands specified for GTP 2,
5//! non-standard extensions are planned for inclusion.
6//! When a command has an effect or may fail,
7//! this should be noted in the documentation.
8
9use super::data;
10use super::gtp_type::*;
11use super::input;
12
13/* Standard Errors
14unknown command
15unacceptable size
16illegal move
17cannot undo
18cannot score
19*/
20
21/// Abstract representation of a command that may be supported by an engine.
22/// Contains the name of the command
23/// as well as the argument and result type specifications.
24#[derive(Debug)]
25pub struct Command {
26	name: String,
27	arguments: <List as data::Data>::Type,
28	response: <MultilineList as data::Data>::Type,
29}
30
31use data::alternatives::Type as Alt;
32use data::collection::Type as Cl;
33use data::list::Type as Lst;
34use data::multiline_list::Type as ML;
35use data::simple_entity::Type as SE;
36
37macro_rules! type_description {
38	( none ) => {
39		Cl::Empty
40	};
41	( int ) => {
42			SE::Int
43	};
44	( float ) => {
45		SE::Float
46	};
47	( string ) => {
48		SE::String
49	};
50	( vertex ) => {
51		SE::Vertex
52	};
53	( color ) => {
54		SE::Color
55	};
56	( move ) => {
57		SE::Motion
58	};
59	( boolean ) => {
60		SE::Boolean
61	};
62	( { } ) => {
63		Cl::Empty
64	};
65	( { $h:tt $( $t:tt ) * } ) => {
66		Cl::Collection(
67			type_description!($h),
68			Box::new(type_description!( { $($t)* } ))
69		)
70	};
71	( $f:tt | $s:tt ) => {
72		<Alt as From<_>>::from((
73			type_description!($f),
74			type_description!($s),
75			))
76	};
77	( $t:tt * ) => {
78		<Lst as From<_>>::from(type_description!($t))
79	};
80	( $t:tt & ) => {
81		<ML as From<_>>::from(type_description!($t))
82	};
83	( $t:tt * & ) => {
84		<ML as From<_>>::from(type_description!($t *))
85	};
86}
87
88// Rustfmt has a weird bug regarding the last lines of this macro.
89#[rustfmt::skip]
90macro_rules! str_to_gtp {
91	( $e:expr ) => {{
92		let s = $e;
93		let i = input::engine::Input::from(s.as_bytes());
94		let t = data::string::Type::default();
95		let (_, r) = <String as data::Data>::parse(i, &t).unwrap();
96		r
97	}};
98}
99
100// TODO: Export this macro.
101/// Specify a new command.
102///
103/// The macro takes three arguments, separated by semicola.
104/// The first is the name of the command, e.g. as string constant,
105/// the other two are the type specification
106/// of the arguments and the response, respectively.
107/// The syntax for specfication of types is not final
108/// and due to restrictions of Rusts macro system
109/// (There appears to be no way to let `*` be a part of the macros syntax
110/// since it is part of the `macro_rules!` syntax.)
111/// not exactly as in the spec.
112//
113// # Examples
114//
115// ```
116// # #[macro_use]
117// # use gorrosion_gtp::command;
118// # use gorrosion_gtp::command::Command;
119// let c: Command = command!("name"; none; [ string ]);
120// ```
121macro_rules! command {
122	($name:expr => ($($args:tt)*) -> ($($resp:tt)*)) => {{
123		let name = str_to_gtp!($name);
124		let arguments = From::from(type_description!($($args)*));
125		let response = From::from(type_description!($($resp)*));
126		Command { name, arguments, response }
127	}};
128}
129
130pub mod administrative;
131pub mod core_play;
132pub mod setup;
133pub mod tournament;
134pub mod regression;
135pub mod debug;