amqp 0.0.18

AMQP/RabbitMQ protocol client
Documentation
// This file is autogenerated. Do not edit.
// To make changes to this file, edit codegen.rb and/or codegen.erb and run make

use framing::{FrameType, Frame};
use amqp_error::{AMQPError, AMQPResult};
use std::io::{Read, Write};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

pub trait Method : Sized {
    fn decode(method_frame: MethodFrame) -> AMQPResult<Self>;
    fn encode(&self) -> AMQPResult<Vec<u8>>;
    fn name(&self) -> &'static str;
    fn id(&self) -> u16;
    fn class_id(&self) -> u16;
}


#[derive(Debug, Clone)]
pub struct MethodFrame {
    pub class_id: u16,
    pub method_id: u16,
    pub arguments: Vec<u8>
}

impl MethodFrame {
    pub fn encode_method<T>(method: &T) -> AMQPResult<Vec<u8>> where T: Method {
        let frame = MethodFrame {class_id: method.class_id(), method_id: method.id(), arguments: try!(method.encode())};
        frame.encode()
    }
    pub fn encode(&self) -> AMQPResult<Vec<u8>> {
        let mut writer = vec![];
        try!(writer.write_u16::<BigEndian>(self.class_id));
        try!(writer.write_u16::<BigEndian>(self.method_id));
        try!(writer.write_all(&self.arguments));
        Ok(writer)
    }

    // We need this method, so we can match on class_id & method_id
    pub fn decode(frame: &Frame) -> AMQPResult<MethodFrame> {
        if frame.frame_type != FrameType::METHOD {
            return Err(AMQPError::DecodeError("Not a method frame"))
        }
        let reader = &mut &frame.payload[..];
        let class_id = try!(reader.read_u16::<BigEndian>());
        let method_id = try!(reader.read_u16::<BigEndian>());
        let mut arguments = vec![];
        try!(reader.read_to_end(&mut arguments));
        Ok(MethodFrame { class_id: class_id, method_id: method_id, arguments: arguments})
    }

    pub fn method_name(&self) -> &'static str {
        match (self.class_id, self.method_id) {
<% matches.each do |m| -%>
          <%= m %>,
<% end -%>
          (_,_) => "UNKNOWN"
        }
    }
}


<% classes.each do |klass| %>
#[allow(unused_imports)]
#[allow(missing_copy_implementations)]
pub mod <%= klass["name"] %> {
    use bit_vec::BitVec;
    use table;
    use table::{Table, decode_table, encode_table};
    use protocol::{Method, MethodFrame};
    use framing::ContentHeaderFrame;
    use amqp_error::{AMQPResult, AMQPError};
    use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
    use std::io::{Read, Write};


<% if klass["properties"] && klass["properties"].any? -%>
    //properties struct for <%= klass["name"] %>
    #[derive(Debug, Default, Clone)]
    pub struct <%= klass["properties_struct_name"] %> {
<% klass["properties_fields"].join(",\n").split("\n").each do |f| -%>
       <%= f %>
<% end -%>
    }

    impl <%= klass["properties_struct_name"] %> {
        pub fn decode(content_header_frame: ContentHeaderFrame) -> AMQPResult<<%=klass["properties_struct_name"]%>> {
            let reader = &mut &content_header_frame.properties[..];
            let properties_flags = BitVec::from_bytes(&[((content_header_frame.properties_flags >> 8) & 0xff) as u8,
                (content_header_frame.properties_flags & 0xff) as u8]);
<% klass["properties"].each.with_index do |prop, idx| -%>
            let <%= prop["prop_name"] %> = match properties_flags.get(<%= idx %>) {
              Some(flag) if flag => Some(<%=read_type(prop["prop_type"])%>),
              None => return Err(AMQPError::Protocol("Properties flags are not correct".to_owned())),
              _ => None
            };
<% end -%>
            Ok(<%=klass["properties_struct_name"]%> { <%= klass["properties_struct_create"].join(", ") %> })
        }

        pub fn encode(self) -> AMQPResult<Vec<u8>> {
            let mut writer = vec![];
<% klass["properties"].each.with_index do |prop, idx| -%>
              match self.<%= prop["prop_name"] %> {
                  Some(prop) => {
                      let <%= prop["prop_name"] %> =  prop;
                      <%= write_type(prop["prop_name"], prop["prop_type"]) %>
                  }
                  None => {}
              };
<% end -%>
            Ok(writer)
        }

        pub fn flags(&self) -> u16 {
            let mut bits = BitVec::from_elem(16, false);
<% klass["properties"].each.with_index do |prop, idx| -%>
            bits.set(<%= idx %>, self.<%= prop["prop_name"] %>.is_some());
<% end -%>
            let flags : u16 = bits.to_bytes()[0] as u16;
            (flags << 8 | bits.to_bytes()[1] as u16) as u16
        }
    }
<% end -%>

<% klass["methods"].each do |method| -%>
    // Method <%= method["id"] %>:<%=method["name"] %>
    #[derive(Debug)]
<% if method["fields"].any? -%>
    pub struct <%= method["method_name"] %> {
<% method["fields"].join(",\n").split("\n").each do |f| -%>
        <%= f %>
<% end -%>
    }
<% else -%>
    pub struct <%= method["method_name"] %>;
<% end -%>

    impl Method for <%= method["method_name"] %> {
        fn name(&self) -> &'static str {
            "<%= klass["name"] %>.<%= method["name"] %>"
        }

        fn id(&self) -> u16 {
            <%= method["id"] %>
        }

        fn class_id(&self) -> u16 {
            <%= klass["id"] %>
        }

        fn decode(method_frame: MethodFrame) -> AMQPResult<<%= method["method_name"] %>> {
            match (method_frame.class_id, method_frame.method_id) {
                (<%= klass["id"] %>, <%= method["id"] %>) => {},
                (_,_) => {return Err(AMQPError::DecodeError("Frame class_id & method_id didn't match"))}
            };
<% if method["arguments"].any? -%>
<% method["readers"].each do |reader| -%>
            <%= reader %>
<% end -%>
            Ok(<%= method["method_name"]%> { <%= method["method_struct_create"].join(", ")  %> })
<% else -%>
            Ok(<%= method["method_name"]%>)
<% end -%>
          }

        fn encode(&self) -> AMQPResult<Vec<u8>> {
<% if method["arguments"].any? -%>
<% method["writers"].each do |writer| -%>
            <%= writer %>
<% end -%>
<% else -%>
            Ok(vec![])
<% end -%>
        }
    }

<% if method["arguments"].any? && method["arguments"].count{|arg| arg["default-value"]} > 0 -%>
    impl <%= method["method_name"] %> {
        pub fn with_default_values(<%= args_list(method["arguments"].reject{|arg| arg["default-value"]}).join(", ") %>) -> <%= method["method_name"] %> {
            <%= method["method_name"] %> {
<% method["arguments"].select{|arg| arg["default-value"]}.each do |arg| -%>
                <%= snake_name(arg["name"]) %>: <%= value_to_rust_value(arg["default-value"]) %>,
<% end -%>
<% method["arguments"].reject{|arg| arg["default-value"]}.each do |arg| -%>
                <%= snake_name(arg["name"]) %>: <%= snake_name(arg["name"]) %>,
<% end -%>
            }
        }
    }
<% end #method["arguments"].any-%>

<% end #methods each-%>
}
<% end #classes each -%>