codegen updated
This commit is contained in:
parent
bb6d47d0cd
commit
729f9c803d
@ -104,13 +104,17 @@ fn serialize_item(
|
|||||||
$size_expr
|
$size_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError> {
|
fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque<usize>) -> Result<(), BinaryConvertError> {
|
||||||
$write_expr
|
$write_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_bytes(buffer: &[u8]) -> Result<Self, BinaryConvertError> {
|
fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque<usize>) -> Result<Self, BinaryConvertError> {
|
||||||
$read_expr
|
$read_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn len_params() -> usize {
|
||||||
|
1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
).unwrap())
|
).unwrap())
|
||||||
}
|
}
|
||||||
@ -158,23 +162,6 @@ struct BinaryExpressions {
|
|||||||
pub read: P<ast::Expr>,
|
pub read: P<ast::Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_variable_size(ty: &P<Ty>) -> bool {
|
|
||||||
match ty.node {
|
|
||||||
TyKind::Vec(_) => true,
|
|
||||||
TyKind::FixedLengthVec(_, _) => false,
|
|
||||||
TyKind::Path(_, ref path) => {
|
|
||||||
path.segments[0].identifier.name.as_str() == "Option" ||
|
|
||||||
path.segments[0].identifier.name.as_str() == "Result" ||
|
|
||||||
path.segments[0].identifier.name.as_str() == "String"
|
|
||||||
},
|
|
||||||
_ => { false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn variable_sizes(cx: &ExtCtxt, fields: &[ast::StructField]) -> Vec<bool> {
|
|
||||||
fields.iter().map(|field| is_variable_size(&field.ty)).collect::<Vec<bool>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn binary_expr_struct(
|
fn binary_expr_struct(
|
||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
@ -183,24 +170,26 @@ fn binary_expr_struct(
|
|||||||
value_ident: Option<ast::Ident>,
|
value_ident: Option<ast::Ident>,
|
||||||
instance_ident: Option<ast::Ident>,
|
instance_ident: Option<ast::Ident>,
|
||||||
) -> Result<BinaryExpressions, Error> {
|
) -> Result<BinaryExpressions, Error> {
|
||||||
let variable_sizes = variable_size_indexes(fields);
|
|
||||||
|
|
||||||
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
|
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
|
||||||
if variable_sizes[index] {
|
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty));
|
||||||
let index_ident = builder.id(format!("__field{}", index));
|
let index_ident = builder.id(format!("__field{}", index));
|
||||||
value_ident.and_then(|x| {
|
value_ident.and_then(|x| {
|
||||||
let field_id = builder.id(field.ident.unwrap());
|
let field_id = builder.id(field.ident.unwrap());
|
||||||
Some(quote_expr!(cx, $x . $field_id .size()))
|
Some(quote_expr!(cx,
|
||||||
|
match $field_type_ident::len_params() {
|
||||||
|
0 => mem::size_of::<$field_type_ident>(),
|
||||||
|
_ => $x. $field_id .size()
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| quote_expr!(cx, $index_ident .size()))
|
.unwrap_or_else(|| quote_expr!(cx, match $field_type_ident::len_params() {
|
||||||
}
|
0 => mem::size_of::<$field_type_ident>(),
|
||||||
else {
|
_ => $index_ident .size()
|
||||||
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty));
|
}))
|
||||||
quote_expr!(cx, mem::sizeof_of::<field_type_ident>());
|
|
||||||
}
|
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let mut total_size_expr = size_exprs[0].clone();
|
let first_size_expr = size_exprs[0].clone();
|
||||||
|
let mut total_size_expr = quote_expr!(cx, 0usize + $first_size_expr);
|
||||||
for index in 1..size_exprs.len() {
|
for index in 1..size_exprs.len() {
|
||||||
let next_expr = size_exprs[index].clone();
|
let next_expr = size_exprs[index].clone();
|
||||||
total_size_expr = quote_expr!(cx, $total_size_expr + $next_expr);
|
total_size_expr = quote_expr!(cx, $total_size_expr + $next_expr);
|
||||||
@ -215,25 +204,36 @@ fn binary_expr_struct(
|
|||||||
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap());
|
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap());
|
||||||
for (index, field) in fields.iter().enumerate() {
|
for (index, field) in fields.iter().enumerate() {
|
||||||
let size_expr = &size_exprs[index];
|
let size_expr = &size_exprs[index];
|
||||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + $size_expr; ).unwrap());
|
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty));
|
||||||
match value_ident {
|
|
||||||
|
let member_expr = match value_ident {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let field_id = builder.id(field.ident.unwrap());
|
let field_id = builder.id(field.ident.unwrap());
|
||||||
write_stmts.push(
|
quote_expr!(cx, $x . $field_id)
|
||||||
quote_stmt!(cx, $x . $field_id .to_bytes(&mut buffer[offset..next_line]);).unwrap())
|
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let index_ident = builder.id(format!("__field{}", index));
|
let index_ident = builder.id(format!("__field{}", index));
|
||||||
write_stmts.push(
|
quote_expr!(cx, $index_ident)
|
||||||
quote_stmt!(cx, $index_ident .to_bytes(&mut buffer[offset..next_line]);).unwrap())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
write_stmts.push(quote_stmt!(cx, let next_line = offset + match $field_type_ident::len_params() {
|
||||||
|
0 => mem::size_of::<$field_type_ident>(),
|
||||||
|
_ => { let size = $member_expr .size(); length_stack.push_back(size); size }
|
||||||
|
}).unwrap());
|
||||||
|
|
||||||
|
write_stmts.push(quote_stmt!(cx,
|
||||||
|
$member_expr .to_bytes(&mut buffer[offset..next_line], length_stack);).unwrap());
|
||||||
|
|
||||||
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
|
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
|
||||||
|
|
||||||
let field_index = builder.id(&format!("{}", index));
|
let field_index = builder.id(&format!("{}", index));
|
||||||
let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty));
|
|
||||||
map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap());
|
map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap());
|
||||||
map_stmts.push(quote_stmt!(cx, total = total + mem::size_of::<$field_type_ident>();).unwrap());
|
map_stmts.push(quote_stmt!(cx, let size = match $field_type_ident::len_params() {
|
||||||
|
0 => mem::size_of::<$field_type_ident>(),
|
||||||
|
_ => length_stack.pop_front().unwrap()
|
||||||
|
}).unwrap());
|
||||||
|
map_stmts.push(quote_stmt!(cx, total = total + size;).unwrap());
|
||||||
};
|
};
|
||||||
|
|
||||||
let read_expr = if value_ident.is_some() {
|
let read_expr = if value_ident.is_some() {
|
||||||
@ -386,6 +386,10 @@ fn fields_sequence(
|
|||||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
|
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||||
|
|
||||||
|
tt.push(Token(_sp, token::Comma));
|
||||||
|
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack"), token::Plain)));
|
||||||
|
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||||
tt.push(Token(_sp, token::Comma));
|
tt.push(Token(_sp, token::Comma));
|
||||||
@ -450,8 +454,14 @@ fn named_fields_sequence(
|
|||||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
|
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"), token::Plain)));
|
||||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
|
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)), token::Plain)));
|
||||||
|
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||||
|
|
||||||
|
tt.push(Token(_sp, token::Comma));
|
||||||
|
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack"), token::Plain)));
|
||||||
|
|
||||||
|
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||||
tt.push(Token(_sp, token::Comma));
|
tt.push(Token(_sp, token::Comma));
|
||||||
|
@ -16,16 +16,17 @@
|
|||||||
|
|
||||||
use ipc::*;
|
use ipc::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
#[derive(Binary)]
|
#[derive(Binary)]
|
||||||
enum Root {
|
pub enum Root {
|
||||||
Top,
|
Top,
|
||||||
Middle(u32, u64),
|
Middle(u32, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Binary)]
|
#[derive(Binary, PartialEq, Debug)]
|
||||||
struct DoubleRoot {
|
pub struct DoubleRoot {
|
||||||
x1: u32,
|
pub x1: u32,
|
||||||
x2: u64,
|
pub x2: u64,
|
||||||
x3: u32,
|
pub x3: u32,
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::super::service::*;
|
use super::super::service::*;
|
||||||
|
use super::super::binary::*;
|
||||||
use super::super::nested::{DBClient,DBWriter};
|
use super::super::nested::{DBClient,DBWriter};
|
||||||
use ipc::*;
|
use ipc::*;
|
||||||
use devtools::*;
|
use devtools::*;
|
||||||
@ -143,4 +144,19 @@ mod tests {
|
|||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_serialize_dummy_structs() {
|
||||||
|
let mut socket = TestSocket::new();
|
||||||
|
|
||||||
|
let struct_ = DoubleRoot { x1: 0, x2: 100, x3: 100000};
|
||||||
|
let res = ::ipc::binary::serialize_into(&struct_, &mut socket);
|
||||||
|
|
||||||
|
assert!(res.is_ok());
|
||||||
|
|
||||||
|
let mut read_socket = TestSocket::new_ready(socket.write_buffer.clone());
|
||||||
|
let new_struct: DoubleRoot = ::ipc::binary::deserialize_from(&mut read_socket).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(struct_, new_struct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user