write completed (hopoefully)

This commit is contained in:
nora 2022-02-13 15:14:42 +01:00
parent 427cfadc11
commit 2aeb588ab3
5 changed files with 117 additions and 113 deletions

View file

@ -5,6 +5,7 @@ use crate::parser::codegen_parser;
use crate::write::codegen_write; use crate::write::codegen_write;
use heck::ToUpperCamelCase; use heck::ToUpperCamelCase;
use std::fs; use std::fs;
use std::iter::Peekable;
use strong_xml::XmlRead; use strong_xml::XmlRead;
#[derive(Debug, XmlRead)] #[derive(Debug, XmlRead)]
@ -191,6 +192,27 @@ fn snake_case(ident: &str) -> String {
} }
} }
fn subsequent_bit_fields<'a>(
amqp: &Amqp,
bit_field: &'a Field,
iter: &mut Peekable<impl Iterator<Item = &'a Field>>,
) -> Vec<&'a Field> {
let mut fields_with_bit = vec![bit_field];
loop {
if iter
.peek()
.map(|f| resolve_type_from_domain(amqp, field_type(f)) == "bit")
.unwrap_or(false)
{
fields_with_bit.push(iter.next().unwrap());
} else {
break;
}
}
fields_with_bit
}
fn invariants<'a>(asserts: impl Iterator<Item = &'a Assert>) -> String { fn invariants<'a>(asserts: impl Iterator<Item = &'a Assert>) -> String {
asserts asserts
.map(|assert| match &*assert.check { .map(|assert| match &*assert.check {

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
field_type, resolve_type_from_domain, snake_case, Amqp, Assert, Class, Domain, Method, field_type, resolve_type_from_domain, snake_case, subsequent_bit_fields, Amqp, Assert, Class,
Domain, Method,
}; };
use heck::{ToSnakeCase, ToUpperCamelCase}; use heck::{ToSnakeCase, ToUpperCamelCase};
use itertools::Itertools; use itertools::Itertools;
@ -99,19 +100,7 @@ fn method_parser(amqp: &Amqp, class: &Class, method: &Method) {
let type_name = resolve_type_from_domain(amqp, field_type(field)); let type_name = resolve_type_from_domain(amqp, field_type(field));
if type_name == "bit" { if type_name == "bit" {
let mut fields_with_bit = vec![field]; let fields_with_bit = subsequent_bit_fields(amqp, field, &mut iter);
loop {
if iter
.peek()
.map(|f| resolve_type_from_domain(amqp, field_type(f)) == "bit")
.unwrap_or(false)
{
fields_with_bit.push(iter.next().unwrap());
} else {
break;
}
}
let amount = fields_with_bit.len(); let amount = fields_with_bit.len();
println!(" let (input, bits) = bit(input, {amount})?;"); println!(" let (input, bits) = bit(input, {amount})?;");

View file

@ -1,4 +1,4 @@
use crate::{field_type, resolve_type_from_domain, snake_case, Amqp}; use crate::{field_type, resolve_type_from_domain, snake_case, subsequent_bit_fields, Amqp};
use heck::ToUpperCamelCase; use heck::ToUpperCamelCase;
pub(crate) fn codegen_write(amqp: &Amqp) { pub(crate) fn codegen_write(amqp: &Amqp) {
@ -26,13 +26,21 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
} }
println!(" }}) => {{"); println!(" }}) => {{");
println!(" writer.write_all(&[{class_index}, {method_index}])?;"); println!(" writer.write_all(&[{class_index}, {method_index}])?;");
for field in &method.fields { let mut iter = method.fields.iter().peekable();
while let Some(field) = iter.next() {
let field_name = snake_case(&field.name); let field_name = snake_case(&field.name);
let field_type = resolve_type_from_domain(amqp, field_type(field)); let type_name = resolve_type_from_domain(amqp, field_type(field));
if field_type == "bit" { if type_name == "bit" {
println!(" todo!();"); let fields_with_bit = subsequent_bit_fields(amqp, field, &mut iter);
print!(" bit(&[");
for field in fields_with_bit {
let field_name = snake_case(&field.name);
print!("{field_name}, ");
}
println!("], &mut writer)?;");
} else { } else {
println!(" {field_type}({field_name}, &mut writer)?;"); println!(" {type_name}({field_name}, &mut writer)?;");
} }
} }
println!(" }}"); println!(" }}");

View file

@ -1106,7 +1106,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[10, 40])?; writer.write_all(&[10, 40])?;
shortstr(virtual_host, &mut writer)?; shortstr(virtual_host, &mut writer)?;
shortstr(reserved_1, &mut writer)?; shortstr(reserved_1, &mut writer)?;
todo!(); bit(&[reserved_2, ], &mut writer)?;
} }
Class::Connection(Connection::OpenOk { Class::Connection(Connection::OpenOk {
reserved_1, reserved_1,
@ -1156,13 +1156,13 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
active, active,
}) => { }) => {
writer.write_all(&[20, 20])?; writer.write_all(&[20, 20])?;
todo!(); bit(&[active, ], &mut writer)?;
} }
Class::Channel(Channel::FlowOk { Class::Channel(Channel::FlowOk {
active, active,
}) => { }) => {
writer.write_all(&[20, 21])?; writer.write_all(&[20, 21])?;
todo!(); bit(&[active, ], &mut writer)?;
} }
Class::Channel(Channel::Close { Class::Channel(Channel::Close {
reply_code, reply_code,
@ -1195,11 +1195,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
shortstr(r#type, &mut writer)?; shortstr(r#type, &mut writer)?;
todo!(); bit(&[passive, durable, reserved_2, reserved_3, no_wait, ], &mut writer)?;
todo!();
todo!();
todo!();
todo!();
table(arguments, &mut writer)?; table(arguments, &mut writer)?;
} }
Class::Exchange(Exchange::DeclareOk { Class::Exchange(Exchange::DeclareOk {
@ -1215,8 +1211,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[40, 20])?; writer.write_all(&[40, 20])?;
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
todo!(); bit(&[if_unused, no_wait, ], &mut writer)?;
todo!();
} }
Class::Exchange(Exchange::DeleteOk { Class::Exchange(Exchange::DeleteOk {
}) => { }) => {
@ -1235,11 +1230,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[50, 10])?; writer.write_all(&[50, 10])?;
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
todo!(); bit(&[passive, durable, exclusive, auto_delete, no_wait, ], &mut writer)?;
todo!();
todo!();
todo!();
todo!();
table(arguments, &mut writer)?; table(arguments, &mut writer)?;
} }
Class::Queue(Queue::DeclareOk { Class::Queue(Queue::DeclareOk {
@ -1265,7 +1256,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
shortstr(routing_key, &mut writer)?; shortstr(routing_key, &mut writer)?;
todo!(); bit(&[no_wait, ], &mut writer)?;
table(arguments, &mut writer)?; table(arguments, &mut writer)?;
} }
Class::Queue(Queue::BindOk { Class::Queue(Queue::BindOk {
@ -1298,7 +1289,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[50, 30])?; writer.write_all(&[50, 30])?;
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
todo!(); bit(&[no_wait, ], &mut writer)?;
} }
Class::Queue(Queue::PurgeOk { Class::Queue(Queue::PurgeOk {
message_count, message_count,
@ -1316,9 +1307,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[50, 40])?; writer.write_all(&[50, 40])?;
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
todo!(); bit(&[if_unused, if_empty, no_wait, ], &mut writer)?;
todo!();
todo!();
} }
Class::Queue(Queue::DeleteOk { Class::Queue(Queue::DeleteOk {
message_count, message_count,
@ -1334,7 +1323,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[60, 10])?; writer.write_all(&[60, 10])?;
long(prefetch_size, &mut writer)?; long(prefetch_size, &mut writer)?;
short(prefetch_count, &mut writer)?; short(prefetch_count, &mut writer)?;
todo!(); bit(&[global, ], &mut writer)?;
} }
Class::Basic(Basic::QosOk { Class::Basic(Basic::QosOk {
}) => { }) => {
@ -1354,10 +1343,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
shortstr(consumer_tag, &mut writer)?; shortstr(consumer_tag, &mut writer)?;
todo!(); bit(&[no_local, no_ack, exclusive, no_wait, ], &mut writer)?;
todo!();
todo!();
todo!();
table(arguments, &mut writer)?; table(arguments, &mut writer)?;
} }
Class::Basic(Basic::ConsumeOk { Class::Basic(Basic::ConsumeOk {
@ -1372,7 +1358,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
}) => { }) => {
writer.write_all(&[60, 30])?; writer.write_all(&[60, 30])?;
shortstr(consumer_tag, &mut writer)?; shortstr(consumer_tag, &mut writer)?;
todo!(); bit(&[no_wait, ], &mut writer)?;
} }
Class::Basic(Basic::CancelOk { Class::Basic(Basic::CancelOk {
consumer_tag, consumer_tag,
@ -1391,8 +1377,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
shortstr(routing_key, &mut writer)?; shortstr(routing_key, &mut writer)?;
todo!(); bit(&[mandatory, immediate, ], &mut writer)?;
todo!();
} }
Class::Basic(Basic::Return { Class::Basic(Basic::Return {
reply_code, reply_code,
@ -1416,7 +1401,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[60, 60])?; writer.write_all(&[60, 60])?;
shortstr(consumer_tag, &mut writer)?; shortstr(consumer_tag, &mut writer)?;
longlong(delivery_tag, &mut writer)?; longlong(delivery_tag, &mut writer)?;
todo!(); bit(&[redelivered, ], &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
shortstr(routing_key, &mut writer)?; shortstr(routing_key, &mut writer)?;
} }
@ -1428,7 +1413,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
writer.write_all(&[60, 70])?; writer.write_all(&[60, 70])?;
short(reserved_1, &mut writer)?; short(reserved_1, &mut writer)?;
shortstr(queue, &mut writer)?; shortstr(queue, &mut writer)?;
todo!(); bit(&[no_ack, ], &mut writer)?;
} }
Class::Basic(Basic::GetOk { Class::Basic(Basic::GetOk {
delivery_tag, delivery_tag,
@ -1439,7 +1424,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
}) => { }) => {
writer.write_all(&[60, 71])?; writer.write_all(&[60, 71])?;
longlong(delivery_tag, &mut writer)?; longlong(delivery_tag, &mut writer)?;
todo!(); bit(&[redelivered, ], &mut writer)?;
shortstr(exchange, &mut writer)?; shortstr(exchange, &mut writer)?;
shortstr(routing_key, &mut writer)?; shortstr(routing_key, &mut writer)?;
long(message_count, &mut writer)?; long(message_count, &mut writer)?;
@ -1456,7 +1441,7 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
}) => { }) => {
writer.write_all(&[60, 80])?; writer.write_all(&[60, 80])?;
longlong(delivery_tag, &mut writer)?; longlong(delivery_tag, &mut writer)?;
todo!(); bit(&[multiple, ], &mut writer)?;
} }
Class::Basic(Basic::Reject { Class::Basic(Basic::Reject {
delivery_tag, delivery_tag,
@ -1464,19 +1449,19 @@ pub fn write_method<W: Write>(class: Class, mut writer: W) -> Result<(), TransEr
}) => { }) => {
writer.write_all(&[60, 90])?; writer.write_all(&[60, 90])?;
longlong(delivery_tag, &mut writer)?; longlong(delivery_tag, &mut writer)?;
todo!(); bit(&[requeue, ], &mut writer)?;
} }
Class::Basic(Basic::RecoverAsync { Class::Basic(Basic::RecoverAsync {
requeue, requeue,
}) => { }) => {
writer.write_all(&[60, 100])?; writer.write_all(&[60, 100])?;
todo!(); bit(&[requeue, ], &mut writer)?;
} }
Class::Basic(Basic::Recover { Class::Basic(Basic::Recover {
requeue, requeue,
}) => { }) => {
writer.write_all(&[60, 110])?; writer.write_all(&[60, 110])?;
todo!(); bit(&[requeue, ], &mut writer)?;
} }
Class::Basic(Basic::RecoverOk { Class::Basic(Basic::RecoverOk {
}) => { }) => {

View file

@ -27,14 +27,14 @@ pub fn longlong<W: Write>(value: Longlong, writer: &mut W) -> Result<(), TransEr
Ok(()) Ok(())
} }
pub fn bit<W: Write>(value: Vec<Bit>, writer: &mut W) -> Result<(), TransError> { pub fn bit<W: Write>(value: &[Bit], writer: &mut W) -> Result<(), TransError> {
// accumulate bits into bytes, starting from the least significant bit in each byte // accumulate bits into bytes, starting from the least significant bit in each byte
// how many bits have already been packed into `current_buf` // how many bits have already been packed into `current_buf`
let mut already_filled = 0; let mut already_filled = 0;
let mut current_buf = 0u8; let mut current_buf = 0u8;
for bit in value { for &bit in value {
if already_filled >= 8 { if already_filled >= 8 {
writer.write_all(&[current_buf])?; writer.write_all(&[current_buf])?;
current_buf = 0; current_buf = 0;