1use super::error::CodecError;
2use super::mechanism::ZmqMechanism;
3
4use bytes::{Bytes, BytesMut};
5
6use std::convert::TryFrom;
7
8pub type ZmtpVersion = (u8, u8);
9
10#[derive(Debug, Copy, Clone)]
11pub struct ZmqGreeting {
12 pub version: ZmtpVersion,
13 pub mechanism: ZmqMechanism,
14 pub as_server: bool,
15}
16
17impl Default for ZmqGreeting {
18 fn default() -> Self {
19 Self {
20 version: (3, 0),
21 mechanism: ZmqMechanism::default(),
22 as_server: false,
23 }
24 }
25}
26
27impl TryFrom<Bytes> for ZmqGreeting {
28 type Error = CodecError;
29
30 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
31 if value.len() != 64 || !(value[0] == 0xff && value[9] == 0x7f) {
32 return Err(CodecError::Greeting("Failed to parse greeting"));
33 }
34 Ok(ZmqGreeting {
35 version: (value[10], value[11]),
36 mechanism: ZmqMechanism::try_from(&value[12..32])?,
37 as_server: value[32] == 0x01,
38 })
39 }
40}
41
42impl From<ZmqGreeting> for BytesMut {
43 fn from(greet: ZmqGreeting) -> Self {
44 let mut data: [u8; 64] = [0; 64];
45 data[0] = 0xff;
46 data[9] = 0x7f;
47 data[10] = greet.version.0;
48 data[11] = greet.version.1;
49 let mech = greet.mechanism.as_str();
50 data[12..12 + mech.len()].copy_from_slice(mech.as_bytes());
51 data[32] = greet.as_server.into();
52 let mut bytes = BytesMut::with_capacity(64);
53 bytes.extend_from_slice(&data);
54 bytes
55 }
56}