Skip to main content

zeromq/codec/
greeting.rs

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}