working serialization gen
This commit is contained in:
parent
3908ddf609
commit
8b1197b335
@ -103,12 +103,13 @@ fn serialize_item(
|
|||||||
$size_expr
|
$size_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bytes(buffer: &mut [u8]) {
|
fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError> {
|
||||||
$write_expr
|
$write_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_bytes(buffer: &[u8]) -> Self {
|
fn from_bytes(buffer: &[u8]) -> Result<Self, BinaryConvertError> {
|
||||||
$read_expr
|
//$read_expr
|
||||||
|
Err(::ipc::BinaryConvertError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).unwrap())
|
).unwrap())
|
||||||
@ -165,7 +166,7 @@ fn binary_expr_struct(
|
|||||||
value_ident: Option<ast::Ident>,
|
value_ident: Option<ast::Ident>,
|
||||||
) -> Result<BinaryExpressions, Error> {
|
) -> Result<BinaryExpressions, Error> {
|
||||||
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)| {
|
||||||
let index_ident = builder.id(format!("{}", index));
|
let index_ident = builder.id(format!("__field{}", index));
|
||||||
value_ident.and_then(|x| Some(quote_expr!(cx, $x . $index_ident .size())))
|
value_ident.and_then(|x| Some(quote_expr!(cx, $x . $index_ident .size())))
|
||||||
.unwrap_or_else(|| quote_expr!(cx, $index_ident .size()))
|
.unwrap_or_else(|| quote_expr!(cx, $index_ident .size()))
|
||||||
}).collect();
|
}).collect();
|
||||||
@ -179,17 +180,18 @@ fn binary_expr_struct(
|
|||||||
let mut write_stmts = Vec::<ast::Stmt>::new();
|
let mut write_stmts = Vec::<ast::Stmt>::new();
|
||||||
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).unwrap());
|
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).unwrap());
|
||||||
for (index, field) in fields.iter().enumerate() {
|
for (index, field) in fields.iter().enumerate() {
|
||||||
let index_ident = builder.id(format!("{}", index));
|
|
||||||
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());
|
write_stmts.push(quote_stmt!(cx, let next_line = offset + $size_expr; ).unwrap());
|
||||||
match value_ident {
|
match value_ident {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
|
let index_ident = builder.id(format!("{}", index));
|
||||||
write_stmts.push(
|
write_stmts.push(
|
||||||
quote_stmt!(cx, $x . $index_ident .write(&mut buffer[offset..next_line]);).unwrap())
|
quote_stmt!(cx, $x . $index_ident .to_bytes(&mut buffer[offset..next_line]);).unwrap())
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
let index_ident = builder.id(format!("__field{}", index));
|
||||||
write_stmts.push(
|
write_stmts.push(
|
||||||
quote_stmt!(cx, $index_ident .write(&mut buffer[offset..next_line]);).unwrap())
|
quote_stmt!(cx, $index_ident .to_bytes(&mut buffer[offset..next_line]);).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
|
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
|
||||||
@ -197,8 +199,8 @@ fn binary_expr_struct(
|
|||||||
|
|
||||||
Ok(BinaryExpressions {
|
Ok(BinaryExpressions {
|
||||||
size: total_size_expr,
|
size: total_size_expr,
|
||||||
write: quote_expr!(cx, { write_stmts; Ok(()) } ),
|
write: quote_expr!(cx, { $write_stmts; Ok(()) } ),
|
||||||
read: quote_expr!(cx, $ty { }),
|
read: quote_expr!(cx, Err(::ipc::BinaryConvertError)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +232,9 @@ fn binary_expr_item_struct(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_bug(span, "#[derive(Binary)] Unsupported struct content, expected tuple/struct");
|
cx.span_bug(span,
|
||||||
|
&format!("#[derive(Binary)] Unsupported struct content, expected tuple/struct, found: {:?}",
|
||||||
|
variant_data));
|
||||||
Err(Error)
|
Err(Error)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -269,7 +273,7 @@ fn binary_expr_enum(
|
|||||||
arms.iter().map(|x| x.read.clone()).collect::<Vec<ast::Arm>>());
|
arms.iter().map(|x| x.read.clone()).collect::<Vec<ast::Arm>>());
|
||||||
|
|
||||||
Ok(BinaryExpressions {
|
Ok(BinaryExpressions {
|
||||||
size: quote_expr!(cx, match *self { $size_arms }),
|
size: quote_expr!(cx, 1usize + match *self { $size_arms }),
|
||||||
write: quote_expr!(cx, match *self { $write_arms }; ),
|
write: quote_expr!(cx, match *self { $write_arms }; ),
|
||||||
read: quote_expr!(cx, match *self { $read_arms }),
|
read: quote_expr!(cx, match *self { $read_arms }),
|
||||||
})
|
})
|
||||||
@ -296,6 +300,17 @@ fn binary_expr_variant(
|
|||||||
let variant_ident = variant.node.name;
|
let variant_ident = variant.node.name;
|
||||||
|
|
||||||
match variant.node.data {
|
match variant.node.data {
|
||||||
|
ast::VariantData::Unit(_) => {
|
||||||
|
let pat = builder.pat().path()
|
||||||
|
.id(type_ident).id(variant_ident)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Ok(BinaryArm {
|
||||||
|
size: quote_arm!(cx, $pat => { 0usize } ),
|
||||||
|
write: quote_arm!(cx, $pat => { Ok(()) } ),
|
||||||
|
read: quote_arm!(cx, $pat => { } ),
|
||||||
|
})
|
||||||
|
},
|
||||||
ast::VariantData::Tuple(ref fields, _) => {
|
ast::VariantData::Tuple(ref fields, _) => {
|
||||||
let field_names: Vec<ast::Ident> = (0 .. fields.len())
|
let field_names: Vec<ast::Ident> = (0 .. fields.len())
|
||||||
.map(|i| builder.id(format!("__field{}", i)))
|
.map(|i| builder.id(format!("__field{}", i)))
|
||||||
@ -319,9 +334,10 @@ fn binary_expr_variant(
|
|||||||
|
|
||||||
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
|
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
|
||||||
|
|
||||||
|
let variant_index_ident = builder.id(format!("{}", variant_index));
|
||||||
Ok(BinaryArm {
|
Ok(BinaryArm {
|
||||||
size: quote_arm!(cx, $pat => { $size_expr } ),
|
size: quote_arm!(cx, $pat => { $size_expr } ),
|
||||||
write: quote_arm!(cx, $pat => { $write_expr } ),
|
write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; let buffer = &mut buffer[1..]; $write_expr } ),
|
||||||
read: quote_arm!(cx, $pat => { $read_expr } ),
|
read: quote_arm!(cx, $pat => { $read_expr } ),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -354,9 +370,11 @@ fn binary_expr_variant(
|
|||||||
read: quote_arm!(cx, $pat => { $read_expr } ),
|
read: quote_arm!(cx, $pat => { $read_expr } ),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => {
|
// _ => {
|
||||||
cx.span_bug(span, "#[derive(Binary)] Unsupported struct content, expected tuple/struct");
|
// cx.span_bug(span,
|
||||||
Err(Error)
|
// &format!("#[derive(Binary)] Unsupported enum variant content, expected tuple/struct, found: {:?}",
|
||||||
},
|
// variant));
|
||||||
|
// Err(Error)
|
||||||
|
// },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,3 +10,4 @@ license = "GPL-3.0"
|
|||||||
ethcore-devtools = { path = "../../devtools" }
|
ethcore-devtools = { path = "../../devtools" }
|
||||||
semver = "0.2.0"
|
semver = "0.2.0"
|
||||||
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
|
ethcore-util = { path = "../../util" }
|
||||||
|
@ -16,12 +16,50 @@
|
|||||||
|
|
||||||
//! Binary representation of types
|
//! Binary representation of types
|
||||||
|
|
||||||
|
use util::bytes::*;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
pub struct BinaryConvertError;
|
pub struct BinaryConvertError;
|
||||||
|
|
||||||
pub trait BinaryConvertable : Sized {
|
pub trait BinaryConvertable : Sized {
|
||||||
fn size(&self) -> Result<usize, BinaryConvertError>;
|
fn size(&self) -> usize;
|
||||||
|
|
||||||
fn to_bytes(buffer: &mut [u8]) -> Result<(), BinaryConvertError>;
|
fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError>;
|
||||||
|
|
||||||
fn from_bytes(buffer: &[u8]) -> Result<Self, BinaryConvertError>;
|
fn from_bytes(buffer: &[u8]) -> Result<Self, BinaryConvertError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! binary_fixed_size {
|
||||||
|
($target_ty: ident) => {
|
||||||
|
impl BinaryConvertable for $target_ty {
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
mem::size_of::<$target_ty>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Result<Self, BinaryConvertError> {
|
||||||
|
match bytes.len().cmp(&::std::mem::size_of::<$target_ty>()) {
|
||||||
|
::std::cmp::Ordering::Less => return Err(BinaryConvertError),
|
||||||
|
::std::cmp::Ordering::Greater => return Err(BinaryConvertError),
|
||||||
|
::std::cmp::Ordering::Equal => ()
|
||||||
|
};
|
||||||
|
let mut res: Self = unsafe { ::std::mem::uninitialized() };
|
||||||
|
res.copy_raw(bytes);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError> {
|
||||||
|
let sz = ::std::mem::size_of::<$target_ty>();
|
||||||
|
let ip: *const $target_ty = self;
|
||||||
|
let ptr: *const u8 = ip as *const _;
|
||||||
|
unsafe {
|
||||||
|
::std::ptr::copy(ptr, buffer.as_mut_ptr(), sz);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_fixed_size!(u64);
|
||||||
|
binary_fixed_size!(u32);
|
||||||
|
binary_fixed_size!(bool);
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
extern crate ethcore_devtools as devtools;
|
extern crate ethcore_devtools as devtools;
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
extern crate nanomsg;
|
extern crate nanomsg;
|
||||||
|
extern crate ethcore_util as util;
|
||||||
|
|
||||||
pub mod interface;
|
pub mod interface;
|
||||||
pub mod binary;
|
pub mod binary;
|
||||||
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
||||||
pub use binary::{BinaryConvertable};
|
pub use binary::{BinaryConvertable, BinaryConvertError};
|
||||||
|
@ -14,8 +14,14 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use ipc::*;
|
||||||
|
|
||||||
#[derive(Binary)]
|
#[derive(Binary)]
|
||||||
enum Root {
|
enum Root {
|
||||||
Top,
|
Top,
|
||||||
Middle(String)
|
Middle(u32, u64),
|
||||||
|
Bottom {
|
||||||
|
number1: u32,
|
||||||
|
number2: u64,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user