slacker 0.1.3

Slacker server built on top of tokio.
Documentation
use nom::{be_u8, be_u16, be_u32, be_i32};

pub const PROTOCOL_VERSION_5: u8 = 5;
pub const RESULT_CODE_SUCCESS: u8 = 0;
pub const RESULT_CODE_NOT_FOUND: u8 = 11;

pub const JSON_CONTENT_TYPE: u8 = 1;

pub const PACKET_TYPE_REQUEST: u8 = 0;
pub const PACKET_TYPE_RESPONSE: u8 = 1;
pub const PACKET_TYPE_PING: u8 = 2;
pub const PACKET_TYPE_PONG: u8 = 3;
pub const PACKET_TYPE_ERROR: u8 = 4;
pub const PACKET_TYPE_INSPECT_REQUEST: u8 = 7;
pub const PACKET_TYPE_INSPECT_RESPONSE: u8 = 8;
pub const PACKET_TYPE_INTERRUPT: u8 = 9;


#[derive(Debug, Copy, Clone)]
pub struct SlackerPacketHeader {
    pub version: u8,
    pub serial_id: i32,
    pub packet_type: u8,
}

named!(slacker_header<SlackerPacketHeader>,
       do_parse!( v: be_u8 >>
                  t: be_i32 >>
                  p: be_u8 >>
                  (
                      SlackerPacketHeader {
                          version: v,
                          serial_id: t,
                          packet_type: p
                      }
                  )));

#[derive(Debug)]
pub struct SlackerRequestPacket {
    pub content_type: u8,
    pub fname: String,
    pub arguments: Vec<u8>,
}

#[derive(Debug)]
pub struct SlackerResponsePacket {
    pub content_type: u8,
    pub result_code: u8,
    pub data: Vec<u8>,
}



#[derive(Debug)]
pub struct SlackerErrorPacket {
    pub result_code: u8,
}


#[derive(Debug)]
pub struct SlackerInspectRequestPacket {
    pub inspect_type: u8,
    pub data: Vec<u8>,
}


#[derive(Debug)]
pub struct SlackerInspectResponsePacket {
    pub data: Vec<u8>,
}


#[derive(Debug)]
pub struct SlackerInterruptPacket {
    pub req_id: i32,
}

#[derive(Debug)]
pub enum SlackerPacketBody {
    Request(SlackerRequestPacket),
    Response(SlackerResponsePacket),
    Error(SlackerErrorPacket),
    InspectRequest(SlackerInspectRequestPacket),
    InspectResponse(SlackerInspectResponsePacket),
    Interrupt(SlackerInterruptPacket),
    Ping,
    Pong,
}

named!(slacker_request <&[u8], SlackerPacketBody>,
       do_parse!( ct: be_u8 >>
                  fname_len: be_u16 >>
                  fname: take_str!(fname_len) >>
                  args_len: be_u32 >>
                  args: take!(args_len) >>
                  (
                      SlackerPacketBody::Request(
                          SlackerRequestPacket {
                              content_type: ct,
                              fname: fname.to_owned(),
                              arguments: args.into()
                          }
                      )
                  )));


named!(slacker_response <&[u8], SlackerPacketBody>,
       do_parse!(ct: be_u8 >>
                 rt: be_u8 >>
                 data_len: be_u32 >>
                 data: take!(data_len) >>
                 (
                     SlackerPacketBody::Response(
                         SlackerResponsePacket {
                             content_type: ct,
                             result_code: rt,
                             data: data.into()
                         })
                 )));

named!(slacker_error <&[u8], SlackerPacketBody>,
       do_parse!(rt: be_u8 >>
                 (
                     SlackerPacketBody::Error(
                         SlackerErrorPacket {
                             result_code: rt
                         }
                     )
                 )
       ));

named!(slacker_inspect_req <&[u8], SlackerPacketBody>,
       do_parse!(it: be_u8 >>
                 data_len: be_u16 >>
                 data: take!(data_len) >>
                 (
                     SlackerPacketBody::InspectRequest(
                         SlackerInspectRequestPacket {
                             inspect_type: it,
                             data: data.into()
                         }
                     )
                 )));

named!(slacker_inspect_resp <&[u8], SlackerPacketBody>,
       do_parse!(data_len: be_u16 >>
                 data: take!(data_len) >>
                 (
                     SlackerPacketBody::InspectResponse(
                         SlackerInspectResponsePacket {
                             data: data.into()
                         })
                 )
       ));

named!(slacker_interrupt <&[u8], SlackerPacketBody>,
       do_parse!(req_id: be_i32 >>
                 (
                     SlackerPacketBody::Interrupt(
                         SlackerInterruptPacket {
                             req_id: req_id
                         })
                 )
       ));

#[derive(Debug)]
pub struct SlackerPacket(pub SlackerPacketHeader, pub SlackerPacketBody);

named!(pub slacker_all <&[u8], SlackerPacket>,
       do_parse!(header: slacker_header >>
                 body: switch!(value!(header.packet_type),
                               PACKET_TYPE_REQUEST => call!(slacker_request) |
                               PACKET_TYPE_RESPONSE => call!(slacker_response) |
                               PACKET_TYPE_PING => value!(SlackerPacketBody::Ping) |
                               PACKET_TYPE_PONG => value!(SlackerPacketBody::Pong) |
                               PACKET_TYPE_ERROR => call!(slacker_error) |
                               PACKET_TYPE_INSPECT_REQUEST => call!(slacker_inspect_req) |
                               PACKET_TYPE_INSPECT_RESPONSE => call!(slacker_inspect_resp) |
                               PACKET_TYPE_INTERRUPT => call!(slacker_interrupt)) >>
                 (SlackerPacket(header, body))
       ));