pub mod metadata {
use super::*;
pub const NAME: &str = "{{protocol.name}}";
pub const MAJOR_VERSION: ShortShortUInt = {{protocol.major_version}};
pub const MINOR_VERSION: ShortShortUInt = {{protocol.minor_version}};
pub const REVISION: ShortShortUInt = {{protocol.revision}};
pub const PORT: LongUInt = {{protocol.port}};
pub const COPYRIGHT: &str = r#"{{protocol.copyright}}"#;
}
pub mod constants {
use super::*;
{{#each protocol.constants as |constant| ~}}
pub const {{sanitize_name constant.name}}: {{constant.type}} = {{constant.value}};
{{/each ~}}
}
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPSoftError {
{{#each protocol.soft_errors as |constant| ~}}
{{camel constant.name}},
{{/each ~}}
}
impl AMQPSoftError {
pub fn get_id(&self) -> ShortUInt {
match *self {
{{#each protocol.soft_errors as |constant| ~}}
AMQPSoftError::{{camel constant.name}} => {{constant.value}},
{{/each ~}}
}
}
pub fn from_id(id: ShortUInt) -> Option<AMQPSoftError> {
match id {
{{#each protocol.soft_errors as |constant| ~}}
{{constant.value}} => Some(AMQPSoftError::{{camel constant.name}}),
{{/each ~}}
_ => None,
}
}
}
impl fmt::Display for AMQPSoftError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
{{#each protocol.soft_errors as |constant| ~}}
AMQPSoftError::{{camel constant.name}} => write!(f, "{{{constant.name}}}"),
{{/each ~}}
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPHardError {
{{#each protocol.hard_errors as |constant| ~}}
{{camel constant.name}},
{{/each ~}}
}
impl AMQPHardError {
pub fn get_id(&self) -> ShortUInt {
match *self {
{{#each protocol.hard_errors as |constant| ~}}
AMQPHardError::{{camel constant.name}} => {{constant.value}},
{{/each ~}}
}
}
pub fn from_id(id: ShortUInt) -> Option<AMQPHardError> {
match id {
{{#each protocol.hard_errors as |constant| ~}}
{{constant.value}} => Some(AMQPHardError::{{camel constant.name}}),
{{/each ~}}
_ => None,
}
}
}
impl fmt::Display for AMQPHardError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
{{#each protocol.hard_errors as |constant| ~}}
AMQPHardError::{{camel constant.name}} => write!(f, "{{{constant.name}}}"),
{{/each ~}}
}
}
}
{{#each protocol.classes as |class| ~}}
use self::{{snake class.name}}::parse_{{snake class.name}};
{{/each ~}}
pub fn parse_class<I: ParsableInput>(i: I) -> ParserResult<I, AMQPClass> {
context("parse_class", map_opt(flat_map(parse_id, |id| move |i| match id {
{{#each protocol.classes as |class| ~}}
{{class.id}} => map(map(parse_{{snake class.name false}}, AMQPClass::{{camel class.name}}), Some)(i),
{{/each ~}}
_ => Ok((i, None)),
}), std::convert::identity))(i)
}
pub fn gen_class<'a, W: Write + BackToTheBuffer + 'a>(class: &'a AMQPClass) -> impl SerializeFn<W> + 'a {
move |input| match *class {
{{#each protocol.classes as |class| ~}}
AMQPClass::{{camel class.name}}(ref {{snake class.name}}) => {{snake class.name}}::gen_{{snake class.name false}}({{snake class.name}})(input),
{{/each ~}}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPClass {
{{#each protocol.classes as |class| ~}}
{{camel class.name}}({{snake class.name}}::AMQPMethod),
{{/each ~}}
}
impl AMQPClass {
pub fn get_amqp_class_id(&self) -> u16 {
match self {
{{#each protocol.classes as |class| ~}}
AMQPClass::{{camel class.name}}(_) => {{class.id}},
{{/each ~}}
}
}
pub fn get_amqp_method_id(&self) -> u16 {
match self {
{{#each protocol.classes as |class| ~}}
{{#each class.methods as |method| ~}}
AMQPClass::{{camel class.name}}({{snake class.name}}::AMQPMethod::{{camel method.name}}(_)) => {{method.id}},
{{/each ~}}
{{/each ~}}
}
}
}
{{#each protocol.classes as |class|}}
pub mod {{snake class.name}} {
use super::*;
pub fn parse_{{snake class.name false}}<I: ParsableInput>(i: I) -> ParserResult<I, {{snake class.name}}::AMQPMethod> {
context("parse_{{snake class.name false}}", map_opt(flat_map(parse_id, |id| move |i| match id {
{{#each class.methods as |method| ~}}
{{method.id}} => context("parse_{{snake method.name false}}", map(map(parse_{{snake method.name false}}, AMQPMethod::{{camel method.name}}), Some))(i),
{{/each ~}}
_ => Ok((i, None)),
}), std::convert::identity))(i)
}
pub fn gen_{{snake class.name false}}<'a, W: Write + BackToTheBuffer + 'a>(method: &'a AMQPMethod) -> impl SerializeFn<W> + 'a {
cookie_factory::sequence::pair(
gen_id({{class.id}}),
move |input| match *method {
{{#each class.methods as |method| ~}}
AMQPMethod::{{camel method.name}}(ref {{snake method.name}}) => {
gen_{{snake method.name false}}({{snake method.name}})(input)
},
{{/each ~}}
}
)
}
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPMethod {
{{#each class.methods as |method| ~}}
{{camel method.name}}({{camel method.name}}),
{{/each ~}}
}
{{#each class.methods as |method|}}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct {{camel method.name}} {
{{#each_argument method.arguments as |argument| ~}}
{{#if @argument_is_value ~}}
{{#unless argument.force_default ~}}
pub {{snake argument.name}}: {{argument.type}},
{{/unless ~}}
{{else}}
{{#unless argument.ignore_flags ~}}
{{#each argument.flags as |flag| ~}}
{{#unless flag.force_default ~}}
pub {{snake flag.name}}: Boolean,
{{/unless ~}}
{{/each ~}}
{{/unless ~}}
{{/if ~}}
{{/each_argument ~}}
}
impl {{camel method.name}} {
pub fn get_amqp_class_id(&self) -> u16 {
{{class.id}}
}
pub fn get_amqp_method_id(&self) -> u16 {
{{method.id}}
}
}
pub fn parse_{{snake method.name false}}<I: ParsableInput>(i: I) -> ParserResult<I, {{camel method.name}}> {
{{#each_argument method.arguments as |argument| ~}}
{{#if @argument_is_value ~}}
let (i, {{#if argument.force_default ~}}_{{else}}{{snake argument.name}}{{/if ~}}) = parse_{{snake_type argument.type}}(i)?;
{{else}}
let (i, {{#if argument.ignore_flags ~}}_{{else}}flags{{/if ~}}) = parse_flags(i, &[
{{#each argument.flags as |flag| ~}}
"{{flag.name}}",
{{/each ~}}
])?;
{{/if ~}}
{{/each_argument ~}}
Ok((i, {{camel method.name}} {
{{#each_argument method.arguments as |argument| ~}}
{{#if @argument_is_value ~}}
{{#unless argument.force_default ~}}
{{snake argument.name}},
{{/unless ~}}
{{else}}
{{#unless argument.ignore_flags ~}}
{{#each argument.flags as |flag| ~}}
{{#unless flag.force_default ~}}
{{snake flag.name}}: flags.get_flag("{{snake flag.name}}").unwrap_or({{flag.default_value}}),
{{/unless ~}}
{{/each ~}}
{{/unless ~}}
{{/if ~}}
{{/each_argument ~}}
}))
}
pub fn gen_{{snake method.name false}}<'a, W: Write + BackToTheBuffer + 'a>({{#if method.arguments ~}}{{#if method.ignore_args ~}}_{{/if ~}}method{{else}}_{{/if ~}}: &'a {{camel method.name}}) -> impl SerializeFn<W> + 'a {
move |mut input| {
{{#each_argument method.arguments as |argument| ~}}
{{#unless @argument_is_value ~}}
let mut flags = AMQPFlags::default();
{{#each argument.flags as |flag| ~}}
flags.add_flag("{{snake flag.name}}".to_string(), {{#if flag.force_default ~}}{{flag.default_value}}{{else}}method.{{snake flag.name}}{{/if ~}});
{{/each ~}}
{{/unless ~}}
{{/each_argument ~}}
input = gen_id({{method.id}})(input)?;
{{#each_argument method.arguments as |argument| ~}}
{{#if @argument_is_value ~}}
{{#if argument.force_default ~}}
{{/if ~}}
input = gen_{{snake_type argument.type}}({{#if (and (pass_by_ref argument.type) (not (use_str_ref argument.type))) ~}}&{{/if ~}}{{#if argument.force_default ~}}{{amqp_value_ref argument.default_value}}{{else}}method.{{snake argument.name}}{{#if (use_str_ref argument.type) ~}}.as_str(){{/if ~}}{{/if ~}})(input)?;
{{else}}
input = gen_flags(&flags)(input)?;
{{/if ~}}
{{/each_argument ~}}
Ok(input)
}
}
{{/each ~}}
{{#if class.properties ~}}
#[derive(Clone, Debug, PartialEq)]
pub struct AMQPProperties {
{{#each class.properties as |property| ~}}
{{snake property.name}}: Option<{{property.type}}>,
{{/each ~}}
}
impl Default for AMQPProperties {
fn default() -> AMQPProperties {
AMQPProperties {
{{#each class.properties as |property| ~}}
{{snake property.name}}: None,
{{/each ~}}
}
}
}
impl AMQPProperties {
{{#each class.properties as |property| ~}}
pub fn with_{{snake property.name false}}(mut self, value: {{property.type}}) -> AMQPProperties {
self.{{snake property.name}} = Some(value);
self
}
{{/each ~}}
{{#each class.properties as |property| ~}}
pub fn {{snake property.name}}(&self) -> &Option<{{property.type}}> {
&self.{{snake property.name}}
}
{{/each ~}}
#[allow(clippy::identity_op)]
pub fn bitmask(&self) -> ShortUInt {
{{#each class.properties as |property| ~}}
(if self.{{snake property.name}}.is_some() { 1 << (15 - {{@index}}) } else { 0 }) {{#unless @last ~}} + {{/unless ~}}
{{/each ~}}
}
}
#[allow(clippy::identity_op)]
pub fn parse_properties<I: ParsableInput>(i: I) -> ParserResult<I, AMQPProperties> {
let (i, flags) = parse_short_uint(i)?;
{{#each class.properties as |property| ~}}
let (i, {{snake property.name}}) = if flags & (1 << (15 - {{@index}})) != 0 { map(parse_{{snake_type property.type}}, Some)(i)? } else { (i, None) };
{{/each ~}}
Ok((i, AMQPProperties {
{{#each class.properties as |property| ~}}
{{snake property.name}},
{{/each ~}}
}))
}
pub fn gen_properties<'a, W: Write + BackToTheBuffer + 'a>(props: &'a AMQPProperties) -> impl SerializeFn<W> + 'a {
cookie_factory::sequence::pair(
gen_short_uint(props.bitmask()),
move |mut input| {
{{#each class.properties as |property| ~}}
if let Some(prop) = props.{{snake property.name}}{{#if (pass_by_ref property.type) ~}}.as_ref(){{/if ~}} {
input = gen_{{snake_type property.type}}(prop{{#if (use_str_ref property.type) ~}}.as_str(){{/if ~}})(input)?;
}
{{/each ~}}
Ok(input)
}
)
}
{{/if ~}}
}
{{/each ~}}