queen_core/wire_protocol/
header.rs1use std::fmt;
2use std::io::{Read, Write};
3
4use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
5use super::error::Result;
6use super::error::Error::ResponseError;
7
8#[derive(Debug, Clone)]
9pub enum OpCode {
10 Request = 1,
11 Response = 2
12}
13
14impl OpCode {
15 pub fn from_i32(i: i32) -> Option<OpCode> {
16 match i {
17 1 => Some(OpCode::Request),
18 2 => Some(OpCode::Response),
19 _ => None
20 }
21 }
22}
23
24impl fmt::Display for OpCode {
25 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
26 match *self {
27 OpCode::Request => write!(fmt, "OP_REQUEST"),
28 OpCode::Response => write!(fmt, "OP_RESPONSE")
29 }
30 }
31}
32
33#[derive(Debug, Clone)]
34pub struct Header {
35 pub message_length: i32,
36 pub request_id: i32,
37 pub response_to: i32,
38 pub op_code: OpCode
39}
40
41impl Header {
42 pub fn new(message_length: i32, request_id: i32, response_to: i32, op_code: OpCode) -> Header {
43 Header {
44 message_length: message_length,
45 request_id: request_id,
46 response_to: response_to,
47 op_code: op_code
48 }
49 }
50
51 pub fn new_request(message_length: i32, request_id: i32) -> Header {
52 Header::new(message_length, request_id, 0, OpCode::Request)
53 }
54
55 pub fn new_response(message_length: i32, response_to: i32) -> Header {
56 Header::new(message_length, 0, response_to, OpCode::Response)
57 }
58
59 pub fn write<W: Write>(&self, buffer: &mut W) -> Result<()> {
60 buffer.write_i32::<LittleEndian>(self.message_length)?;
61 buffer.write_i32::<LittleEndian>(self.request_id)?;
62 buffer.write_i32::<LittleEndian>(self.response_to)?;
63 buffer.write_i32::<LittleEndian>(self.op_code.clone() as i32)?;
64
65 Ok(())
66 }
67
68 pub fn read<R: Read>(buffer: &mut R) -> Result<Header> {
69 let message_length = buffer.read_i32::<LittleEndian>()?;
70 let request_id = buffer.read_i32::<LittleEndian>()?;
71 let response_to = buffer.read_i32::<LittleEndian>()?;
72 let op_code_i32 = buffer.read_i32::<LittleEndian>()?;
73
74 let op_code = match OpCode::from_i32(op_code_i32) {
75 Some(code) => code,
76 _ => return Err(ResponseError(format!("Invalid header opcode from server: {}.", op_code_i32)))
77 };
78
79 Ok(Header::new(message_length, request_id, response_to, op_code))
80 }
81}