Merge branch 'master' into client-ipc-refact
This commit is contained in:
@@ -22,5 +22,5 @@ aster = { version = "0.17", default-features = false }
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
quasi = { version = "0.11", default-features = false }
|
||||
quasi_macros = { version = "0.11", optional = true }
|
||||
syntex = { version = "*", optional = true }
|
||||
syntex_syntax = { version = "*", optional = true }
|
||||
syntex = { version = "0.33", optional = true }
|
||||
syntex_syntax = { version = "0.33", optional = true }
|
||||
|
||||
@@ -201,15 +201,20 @@ fn implement_dispatch_arm_invoke_stmt(
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&function_name, ext_cx).into_iter());
|
||||
@@ -221,12 +226,25 @@ fn implement_dispatch_arm_invoke_stmt(
|
||||
}
|
||||
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
}
|
||||
else {
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Semi));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new"))));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
}
|
||||
tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
tt
|
||||
})).unwrap()
|
||||
}
|
||||
@@ -497,9 +515,9 @@ fn client_generics(builder: &aster::AstBuilder, interface_map: &InterfaceMap) ->
|
||||
.build()
|
||||
}
|
||||
|
||||
fn client_qualified_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P<Ty> {
|
||||
fn client_qualified_ident(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P<Ty> {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(builder))
|
||||
aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item))
|
||||
.with_generics(generics).build()
|
||||
.build()
|
||||
}
|
||||
@@ -515,7 +533,7 @@ fn client_phantom_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMa
|
||||
/// for say `Service` it generates `ServiceClient`
|
||||
fn push_client_struct(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap, push: &mut FnMut(Annotatable)) {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(builder);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item);
|
||||
let phantom = client_phantom_ident(builder, interface_map);
|
||||
|
||||
let client_struct_item = quote_item!(cx,
|
||||
@@ -547,9 +565,9 @@ fn push_with_socket_client_implementation(
|
||||
push: &mut FnMut(Annotatable))
|
||||
{
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(cx, builder, interface_map);
|
||||
let where_clause = &generics.where_clause;
|
||||
let client_short_ident = interface_map.ident_map.client_ident(builder);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item);
|
||||
|
||||
let implement = quote_item!(cx,
|
||||
impl $generics ::ipc::WithSocket<S> for $client_ident $where_clause {
|
||||
@@ -578,7 +596,7 @@ fn push_client_implementation(
|
||||
.collect::<Vec<P<ast::ImplItem>>>();
|
||||
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(cx, builder, interface_map);
|
||||
let where_clause = &generics.where_clause;
|
||||
|
||||
let handshake_item = quote_impl_item!(cx,
|
||||
@@ -682,6 +700,52 @@ fn implement_handshake_arm(
|
||||
}
|
||||
|
||||
|
||||
fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<String, ()> {
|
||||
match lit.node {
|
||||
ast::LitKind::Str(ref s, _) => Ok(format!("{}", s)),
|
||||
_ => {
|
||||
cx.span_err(
|
||||
lit.span,
|
||||
&format!("ipc client_ident annotation `{}` must be a string, not `{}`",
|
||||
name,
|
||||
::syntax::print::pprust::lit_to_string(lit)));
|
||||
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ipc_meta_items(attr: &ast::Attribute) -> Option<&[P<ast::MetaItem>]> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref name, ref items) if name == &"ipc" => {
|
||||
Some(items)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn client_ident_renamed(cx: &ExtCtxt, item: &ast::Item) -> Option<String> {
|
||||
for meta_items in item.attrs().iter().filter_map(get_ipc_meta_items) {
|
||||
for meta_item in meta_items {
|
||||
let span = meta_item.span;
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"client_ident" => {
|
||||
if let Ok(s) = get_str_from_lit(cx, name, lit) {
|
||||
return Some(s);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown client_ident container attribute `{}`",
|
||||
::syntax::print::pprust::meta_item_to_string(meta_item)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
struct InterfaceMap {
|
||||
pub original_item: Item,
|
||||
pub item: P<ast::Item>,
|
||||
@@ -700,8 +764,13 @@ impl IdentMap {
|
||||
builder.id(format!("{}", ::syntax::print::pprust::path_to_string(&self.original_path)))
|
||||
}
|
||||
|
||||
fn client_ident(&self, builder: &aster::AstBuilder) -> Ident {
|
||||
builder.id(format!("{}Client", self.original_path.segments[0].identifier))
|
||||
fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder, item: &ast::Item) -> Ident {
|
||||
if let Some(new_name) = client_ident_renamed(cx, item) {
|
||||
builder.id(new_name)
|
||||
}
|
||||
else {
|
||||
builder.id(format!("{}Client", self.original_path.segments[0].identifier))
|
||||
}
|
||||
}
|
||||
|
||||
fn qualified_ident(&self, builder: &aster::AstBuilder) -> Ident {
|
||||
|
||||
@@ -50,11 +50,36 @@ include!("lib.rs.in");
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
pub fn register(reg: &mut syntex::Registry) {
|
||||
use syntax::{ast, fold};
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
|
||||
struct StripAttributeFolder;
|
||||
impl fold::Folder for StripAttributeFolder {
|
||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaItemKind::List(ref n, _) if n == &"ipc" => { return None; }
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Some(attr)
|
||||
}
|
||||
|
||||
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
|
||||
fold::noop_fold_mac(mac, self)
|
||||
}
|
||||
}
|
||||
|
||||
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
|
||||
}
|
||||
|
||||
reg.add_attr("feature(custom_derive)");
|
||||
reg.add_attr("feature(custom_attribute)");
|
||||
|
||||
reg.add_decorator("derive_Ipc", codegen::expand_ipc_implementation);
|
||||
reg.add_decorator("derive_Binary", serialization::expand_serialization_implementation);
|
||||
|
||||
reg.add_post_expansion_pass(strip_attributes);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
@@ -67,4 +92,6 @@ pub fn register(reg: &mut rustc_plugin::Registry) {
|
||||
syntax::parse::token::intern("derive_Binary"),
|
||||
syntax::ext::base::MultiDecorator(
|
||||
Box::new(serialization::expand_serialization_implementation)));
|
||||
|
||||
reg.register_attribute("ipc".to_owned(), AttributeType::Normal);
|
||||
}
|
||||
|
||||
@@ -144,10 +144,8 @@ impl<K, V> BinaryConvertable for BTreeMap<K, V> where K : BinaryConvertable + Or
|
||||
0usize + match K::len_params() {
|
||||
0 => mem::size_of::<K>() * self.len(),
|
||||
_ => self.iter().fold(0usize, |acc, (k, _)| acc + k.size())
|
||||
}
|
||||
+
|
||||
match V::len_params() {
|
||||
0 => mem::size_of::<V>() * self.len(),
|
||||
} + match V::len_params() {
|
||||
0 => mem::size_of::<V>() * self.len(), 0 => mem::size_of::<V>() * self.len(),
|
||||
_ => self.iter().fold(0usize, |acc, (_, v)| acc + v.size())
|
||||
}
|
||||
}
|
||||
@@ -179,7 +177,7 @@ impl<K, V> BinaryConvertable for BTreeMap<K, V> where K : BinaryConvertable + Or
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque<usize> ) -> Result<Self, BinaryConvertError> {
|
||||
fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque<usize>) -> Result<Self, BinaryConvertError> {
|
||||
let mut index = 0;
|
||||
let mut result = Self::new();
|
||||
|
||||
@@ -192,8 +190,7 @@ impl<K, V> BinaryConvertable for BTreeMap<K, V> where K : BinaryConvertable + Or
|
||||
};
|
||||
let key = if key_size == 0 {
|
||||
try!(K::from_empty_bytes())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
try!(K::from_bytes(&buffer[index..index+key_size], length_stack))
|
||||
};
|
||||
index = index + key_size;
|
||||
@@ -204,8 +201,7 @@ impl<K, V> BinaryConvertable for BTreeMap<K, V> where K : BinaryConvertable + Or
|
||||
};
|
||||
let val = if val_size == 0 {
|
||||
try!(V::from_empty_bytes())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
try!(V::from_bytes(&buffer[index..index+val_size], length_stack))
|
||||
};
|
||||
result.insert(key, val);
|
||||
|
||||
@@ -16,5 +16,5 @@ ethcore-ipc-nano = { path = "../nano" }
|
||||
ethcore-util = { path = "../../util" }
|
||||
|
||||
[build-dependencies]
|
||||
syntex = "*"
|
||||
syntex = "0.33"
|
||||
ethcore-ipc-codegen = { path = "../codegen" }
|
||||
|
||||
@@ -58,6 +58,23 @@ pub fn main() {
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
}
|
||||
|
||||
// rpc pass
|
||||
if {
|
||||
let src = Path::new("with_attrs.rs.in");
|
||||
let dst = Path::new(&out_dir).join("with_attrs_ipc.rs");
|
||||
let mut registry = syntex::Registry::new();
|
||||
codegen::register(&mut registry);
|
||||
registry.expand("", &src, &dst).is_ok()
|
||||
}
|
||||
// serialization pass
|
||||
{
|
||||
let src = Path::new(&out_dir).join("with_attrs_ipc.rs");
|
||||
let dst = Path::new(&out_dir).join("with_attrs_cg.rs");
|
||||
let mut registry = syntex::Registry::new();
|
||||
codegen::register(&mut registry);
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
}
|
||||
|
||||
// rpc pass
|
||||
{
|
||||
let src = Path::new("binary.rs.in");
|
||||
|
||||
@@ -86,7 +86,7 @@ mod tests {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 0, 0, 0],
|
||||
service_client.socket().borrow().write_buffer.clone());
|
||||
service_client.socket().write().unwrap().write_buffer.clone());
|
||||
assert_eq!(10, result);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ mod tests {
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().borrow().write_buffer.clone());
|
||||
5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().write().unwrap().write_buffer.clone());
|
||||
assert_eq!(10, result);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ mod tests {
|
||||
// items
|
||||
3, 0, 0, 0, 0, 0, 0, 0,
|
||||
11, 0, 0, 0, 0, 0, 0, 0],
|
||||
service_client.socket().borrow().write_buffer.clone());
|
||||
service_client.socket().write().unwrap().write_buffer.clone());
|
||||
assert_eq!(true, result);
|
||||
}
|
||||
|
||||
@@ -190,4 +190,20 @@ mod tests {
|
||||
|
||||
assert_eq!(struct_, new_struct);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_call_void_method() {
|
||||
let mut socket = TestSocket::new();
|
||||
socket.read_buffer = vec![1];
|
||||
let service_client = ServiceClient::init(socket);
|
||||
|
||||
service_client.void(99);
|
||||
|
||||
assert_eq!(vec![
|
||||
0, 19,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 0, 0, 0, 0, 0, 0, 0,
|
||||
99, 0, 0, 0, 0, 0, 0, 0],
|
||||
service_client.socket().write().unwrap().write_buffer.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
mod tests {
|
||||
|
||||
use super::super::service::*;
|
||||
use super::super::with_attrs::PrettyNamedClient;
|
||||
use nanoipc;
|
||||
use std::sync::Arc;
|
||||
use std::io::Write;
|
||||
@@ -43,6 +44,12 @@ mod tests {
|
||||
assert!(client.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_renamed_client() {
|
||||
let client = nanoipc::init_duplex_client::<PrettyNamedClient<_>>("ipc:///tmp/parity-nano-test10.ipc");
|
||||
assert!(client.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_call_handshake() {
|
||||
let url = "ipc:///tmp/parity-test-nano-20.ipc";
|
||||
|
||||
@@ -28,3 +28,4 @@ mod examples;
|
||||
mod over_nano;
|
||||
mod nested;
|
||||
mod binary;
|
||||
mod with_attrs;
|
||||
|
||||
@@ -39,12 +39,14 @@ impl Service {
|
||||
*lock = *lock + f as usize;
|
||||
f
|
||||
}
|
||||
|
||||
pub fn rollback(&self, a: Option<u32>, b: u32) -> i32 {
|
||||
let a_0 = a.unwrap_or_else(|| 0);
|
||||
let mut lock = self.rollbacks.write().unwrap();
|
||||
*lock = *lock + a_0 as usize - b as usize;
|
||||
(a_0 - b) as i32
|
||||
}
|
||||
|
||||
pub fn push_custom(&self, data: CustomData) -> bool {
|
||||
let mut clock = self.commits.write().unwrap();
|
||||
let mut rlock = self.commits.write().unwrap();
|
||||
@@ -54,6 +56,9 @@ impl Service {
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn void(&self, a: u64) {
|
||||
}
|
||||
}
|
||||
|
||||
impl Service {
|
||||
|
||||
18
ipc/tests/with_attrs.rs
Normal file
18
ipc/tests/with_attrs.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
|
||||
include!(concat!(env!("OUT_DIR"), "/with_attrs_cg.rs"));
|
||||
34
ipc/tests/with_attrs.rs.in
Normal file
34
ipc/tests/with_attrs.rs.in
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::sync::RwLock;
|
||||
use std::ops::*;
|
||||
use ipc::IpcConfig;
|
||||
use std::mem;
|
||||
use ipc::binary::BinaryConvertError;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct BadlyNamedService;
|
||||
|
||||
#[derive(Ipc)]
|
||||
#[ipc(client_ident="PrettyNamedClient")]
|
||||
impl BadlyNamedService {
|
||||
fn is_zero(&self, x: u64) -> bool {
|
||||
x == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::ipc::IpcConfig for BadlyNamedService {}
|
||||
Reference in New Issue
Block a user