aboutsummaryrefslogtreecommitdiff
path: root/src/message/handshake/mod.rs
blob: 022b71f9b08364df06196fb553407f7978a54544 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
mod clientinit;
mod clientinitack;
mod clientinitreject;
mod clientlogin;
mod clientloginack;
mod clientloginreject;
mod connack;
mod features;
mod init;
mod protocol;
mod sessioninit;
mod types;

pub use clientinit::*;
pub use clientinitack::*;
pub use clientinitreject::*;
pub use clientlogin::*;
pub use clientloginack::*;
pub use clientloginreject::*;
pub use connack::*;
pub use features::*;
pub use init::*;
pub use protocol::*;
pub use sessioninit::*;
#[allow(unused_imports)]
pub use types::*;

use crate::error::ProtocolError;
use crate::primitive::VariantMap;
use crate::{HandshakeDeserialize, HandshakeSerialize};

#[derive(Debug, Clone)]
pub enum HandshakeMessage {
    ClientInit(ClientInit),
    ClientInitAck(ClientInitAck),
    ClientInitReject(ClientInitReject),
    ClientLogin(ClientLogin),
    ClientLoginAck,
    ClientLoginReject(ClientLoginReject),
    SessionInit(SessionInit),
}

impl HandshakeSerialize for HandshakeMessage {
    fn serialize(&self) -> Result<Vec<u8>, ProtocolError> {
        match self {
            HandshakeMessage::ClientInit(inner) => inner.serialize(),
            HandshakeMessage::ClientInitAck(inner) => inner.serialize(),
            HandshakeMessage::ClientInitReject(inner) => inner.serialize(),
            HandshakeMessage::ClientLogin(inner) => inner.serialize(),
            HandshakeMessage::ClientLoginAck => ClientLoginAck.serialize(),
            HandshakeMessage::ClientLoginReject(inner) => inner.serialize(),
            HandshakeMessage::SessionInit(inner) => inner.serialize(),
        }
    }
}

impl HandshakeDeserialize for HandshakeMessage {
    fn parse(b: &[u8]) -> Result<(usize, Self), ProtocolError> {
        let (size, res) = VariantMap::parse(b)?;

        let msgtype: String = (&res["MsgType"]).into();
        match msgtype.as_str() {
            "ClientInit" => Ok((size, HandshakeMessage::ClientInit(res.into()))),
            "ClientInitAck" => Ok((size, HandshakeMessage::ClientInitAck(res.into()))),
            "ClientInitReject" => Ok((size, HandshakeMessage::ClientInitReject(res.into()))),
            "ClientLogin" => Ok((size, HandshakeMessage::ClientLogin(res.into()))),
            "ClientLoginAck" => Ok((size, HandshakeMessage::ClientLoginAck)),
            "ClientLoginReject" => Ok((size, HandshakeMessage::ClientLoginReject(res.into()))),
            "SessionInit" => Ok((size, HandshakeMessage::SessionInit(res.into()))),
            _ => unimplemented!(),
        }
    }
}