ruci/messages/gui/
register.rs

1use std::fmt::{Display, Formatter, Write};
2use crate::messages::pointers::gui::{GuiMessageParameterPointer, GuiMessagePointer, GuiMessageRegisterParameterPointer};
3use crate::auxiliary::{MessageTryFromRawMessageError};
4use crate::messages::RawGuiMessage;
5
6#[allow(clippy::module_name_repetitions)]
7#[derive(Debug, Clone, PartialEq, Eq)]
8/// <https://backscattering.de/chess/uci/#gui-register>
9pub enum Register {
10    Later,
11    Name(String),
12    Code(String),
13    NameAndCode { name: String, code: String },
14}
15
16impl TryFrom<RawGuiMessage> for Register {
17    type Error = MessageTryFromRawMessageError<GuiMessageParameterPointer>;
18
19    fn try_from(raw_message: RawGuiMessage) -> Result<Self, Self::Error> {
20        if raw_message.message_pointer != GuiMessagePointer::Register {
21            return Err(Self::Error::InvalidMessage);
22        };
23
24        if let Some(value) = raw_message.value {
25            if value == "later" {
26                return Ok(Self::Later);
27            }
28        }
29
30        let name = raw_message
31            .parameters
32            .get(&GuiMessageParameterPointer::Register(
33                GuiMessageRegisterParameterPointer::Name,
34            ))
35            .cloned();
36
37        let code = raw_message
38            .parameters
39            .get(&GuiMessageParameterPointer::Register(
40                GuiMessageRegisterParameterPointer::Code,
41            ))
42            .cloned();
43
44        #[allow(clippy::option_if_let_else)]
45        if let Some(name) = name {
46            if let Some(code) = code {
47                Ok(Self::NameAndCode {
48                    name,
49                    code,
50                })
51            } else {
52                Ok(Self::Name(name))
53            }
54        } else if let Some(code) = code {
55            Ok(Self::Code(code))
56        } else {
57            Err(Self::Error::MissingParameter(
58                GuiMessageParameterPointer::Register(
59                    GuiMessageRegisterParameterPointer::Name,
60                ),
61            ))
62        }
63    }
64}
65
66impl Display for Register {
67    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68        match self {
69            Self::Later => f.write_str("register later")?,
70            Self::Name(name) => write!(f, "register name {name}")?,
71            Self::Code(code) => write!(f, "register code {code}")?,
72            Self::NameAndCode { name, code } => {
73                write!(f, "register name {name} code {code}")?;
74            }
75        }
76        
77        f.write_char('\n')
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use std::str::FromStr;
84    use pretty_assertions::assert_eq;
85    
86    use crate::messages::{GuiMessage, Register};
87
88    #[test]
89    fn to_from_str() {
90        let repr = GuiMessage::Register(Register::NameAndCode {
91            name: "john smith".to_string(),
92            code: "31 tango".to_string()
93        });
94        let str_repr = "register name john smith code 31 tango\n";
95
96        assert_eq!(repr.to_string(), str_repr);
97        assert_eq!(GuiMessage::from_str(str_repr), Ok(repr));
98    }
99}